瞎扯淡 Github API v3

hooopo for Shopper+ · November 25, 2012 · Last by fsword replied at November 27, 2012 · 13632 hits

@saito 同学在 Twitter 上吐槽了一下..

Hooopo @Hooopo
Github的API v3设计的太赞了!或许是我最近使用公司内部API太多了才会有这种感觉..?

Saito @SaitoWu
@Hooopo Github 业界良心啊.

Hooopo @Hooopo
@SaitoWu 感觉Github的API有点超文本驱动的意思了。目前我们公司的API连正确使用HTTP动词这点都没有共识。

Saito @SaitoWu
@Hooopo 除了 Rails 程序员对于 HTTP verb 偏执之外. 其他 web 程序员都完全不 care verb 这回事. 有的 web 框架后端不区分 GET 与 POST 请求, 更别说 PUT PATCH DELETE 了. 看不惯就撤吧.. orz


Hooopo @Hooopo
@SaitoWu 是哇,程序员在意某个方法的微小性能差异,但对程序整体的伸缩性安全性什么的一点不在意。

Saito @SaitoWu
@Hooopo 这个跟技术背景很有关系, 我有个同学之前是 pure c 的背景. 现在有项目要用到前端. 他很关心 javascript 大对象内存拷贝的事情. 我就从来都没考虑过. 还有些很担心编程语言太灵活好用, 写出来的程序队友看不懂. 这些都是病, 得电.

Hooopo @Hooopo
@__yuan__ http://developer.github.com/v3/#hypermedia  这就是我上次和你讨论的用URI模板发布公共API接口的方式。

Hooopo @Hooopo
@Hooopo @__yuan__ 通过 curl https://api.github.com  返回所有发布的API名称和参数,这样发布API接口就和发布软件接口一样了。发布和升级变得优雅了很多...

Hooopo @Hooopo
http://developer.github.com/v3/#rate-limiting … 给未认证API调用一个很低的请求频率限制,给认证的API请求高的频率限制,并且每次调用在X-RateLimit-Limit提供当前剩余调用次数,保证客户端知道自己的状态。

Hooopo @Hooopo
http://developer.github.com/v3/#conditional-requests … 通过标准的HTTP协议去实现缓存,并且缓存命中时不计入RateLimit。

Hooopo @Hooopo
http://developer.github.com/v3/#json-p-callbacks … JSONP请求返回的Content-Type是application/javascript,普通API调用返回的Content-Type是application/json。好吧 这都是基本的常识,但是很少API接口设置正确。

Hooopo @Hooopo
每个API返回都带一个 X-Content-Type-Options: nosniff 头,这太赞了,程序员应该自己清楚返回的Content-Type,不需要IE的自作聪明...

Saito @SaitoWu
@Hooopo 真正写好 API 要掌握的点非常多啊. 比如 POST 成功的 status 201 设置完之后还得设置一个在 header 里面设置 location. DELETE 成功如果 body 不返回数据要 204 等等. 光 status 就够喝一壶的.

Hooopo @Hooopo
@SaitoWu 嗯 都是HTTP协议的规范呀 可是现在大家都只拿HTTP协议当传输协议。

Saito @SaitoWu
@Hooopo 还好有 Github 这样的, 给开发者也做了表率. 没法强求别人, 先做好自己吧.

http://developer.github.com/v3/

获取 Github 所有发布资源 URI:

curl  https://api.github.com
{
  "emojis_url": "/emojis",
  "user_organizations_url": "/user/orgs",
  "team_url": "/teams",
  "organization_repositories_url": "/orgs/{org}/repos/{?type,page,per_page,sort}",
  "user_url": "/users/{user}",
  "repository_url": "/repos/{owner}/{repo}",
  "notifications_url": "/notifications",
  "hub_url": "/hub",
  "user_search_url": "/legacy/user/search/{keyword}",
  "starred_gists_url": "/gists/starred",
  "issue_search_url": "/legacy/issues/search/{owner}/{repo}/{state}/{keyword}",
  "events_url": "/events",
  "public_gists_url": "/gists/public",
  "organization_url": "/orgs/{org}",
  "issues_url": "/issues",
  "current_user_url": "/user",
  "rate_limit_url": "/rate_limit",
  "authorizations_url": "/authorizations",
  "repository_search_url": "/legacy/repos/search/{keyword}{?language,start_page}",
  "gists_url": "/gists{/gist_id}",
  "following_url": "/user/following{/target}",
  "user_repositories_url": "/users/{user}/repos{?type,page,per_page,sort}",
  "emails_url": "/user/emails",
  "starred_url": "/user/starred{/owner}{/repo}",
  "current_user_repositories_url": "/user/repos{?type,page,per_page,sort}",
  "keys_url": "/user/keys"
}

URI 模板:

>> tmpl = URITemplate.new('/notifications{?since,all,participating}')
>> tmpl.expand
=> "/notifications"

>> tmpl.expand :all => 1
=> "/notifications?all=1"

>> tmpl.expand :all => 1, :participating => 1
=> "/notifications?all=1&participating=1"

>> tmpl.expand :unknown => 1
=> "/notifications"

阁下的这个帖子在豆瓣上被转发和推荐的次数比这里的 0 回复好多了。

大神,小弟没看懂

这是病,得电… 哈哈哈

#6 楼 @huacnlee 不懂啊,求解释!

还有些很担心编程语言太灵活好用, 写出来的程序队友看不懂.

我觉得这个很有道理啊。。。ruby 很容易写成神仙代码的。。

好好一个精品贴生生被你俩变成语录体了,有没有时间写一个 blog 总结一下啊?

hooopo in Modern Web API Desgin mention this topic. 12 Jul 13:47
You need to Sign in before reply, if you don't have an account, please Sign up first.