json|GitHub developer API 学习

官网地址:https://developer.github.com/v3/
目录
当前版本
schema
parameters
root endpoint
client errors
http redirects
http verbs
authentication
hypermedia
pagination
rate limiting
user agent required
conditional requests
cross origin resource sharing
json-p callbacks
timezones
Current Version 当前版本
默认,所有请求都接收v3版本的API。我们推荐显式地请求 -- 通过Accept header。

Accept: application/vnd.github.v3+json

Schema
所有API 的访问都是通过HTTPS,且来自https://api.github.com。 所有数据都以JSON形式来发送和接收。
curl -i https://api.github.com/users/octocat/orgs HTTP/1.1 200 OK Server: nginx Date: Fri, 12 Oct 2012 23:33:14 GMT Content-Type: application/json; charset=utf-8 Connection: keep-alive Status: 200 OK ETag: "a00049ba79152d03380c34652f2cb612" X-GitHub-Media-Type: github.v3 X-RateLimit-Limit: 5000 X-RateLimit-Remaining: 4987 X-RateLimit-Reset: 1350085394 Content-Length: 5 Cache-Control: max-age=0, private, must-revalidate X-Content-Type-Options: nosniff

blank fields(空字段)都是作为null,而非被忽略。
所有的时间戳都以ISO 8601格式返回。
YYYY-MM-DDTHH:MM:SSZ

summary representations 概要描述
当你获取一个资源列表时,响应会包含该资源的attributes的一个子集。这就是该资源的summary representation。(一些attributes是很耗费计算资源的。考虑到性能,summary representation排除了那些attributes。如果想要获取那些attributes,请索要"detailed" representation。)
例子:当你得到一个repositories的列表时,你会得到每个repository的summary representation。
这里,我们索要octokit组织所拥有的repositories列表:
GET /orgs/octokit/repos

Detailed Representations 详细描述
当你索要一个具体的资源时,响应通常会包含该资源的所有attributes。这就是该资源的"detailed" representation。(注意,有时候授权会影响详细信息的总量。)
例子:当你得到一个具体的repository时,你会得到该repository的detailed representation。
这里,我们索要octokit/octokit.rb repository:
GET /repos/octokit/octokit.rb

本文档为每个API method提供了一个示例响应。这些示例响应演示了由method返回的所有attributes。
Parameters 参数
很多API methods接受可选参数。对于GET请求,任何木有出现在path中的参数,都可以作为HTTP query string parameter传递:
curl -i "https://api.github.com/repos/vmg/redcarpet/issues?state=closed"

在这个例子中,vmg和redcarpet的值是提供给 :owner和 :repo parameters的,而 :state则以query string传递。
对于POST、PATCH、PUT、以及DELETE 请求,不包含在URL中的parameters应该被编码成JSON,Content-Type应该是application/json。
curl -i -u username -d '{"scopes":["public_repo"]}' https://api.github.com/authorizations

Root Endpoint 根端点
你可以针对root endpoint发起一个GET请求,以获取该endpoint的所有categories -- API支持的:
curl https://api.github.com

Client Errors 客户端错误
当API调用接收请求体时,根据请求体的不同,有三种类型的可能的客户端错误。
1、发送无效JSON 会导致一个 "404 Bad Request" 响应。
HTTP/1.1 400 Bad Request Content-Length: 35{"message":"Problems parsing JSON"}

2、发送错误类型的JSON值 会导致一个 "404 Bad Request" 响应。
HTTP/1.1 400 Bad Request Content-Length: 40{"message":"Body should be a JSON object"}

3、发送无效字段会导致一个 "422 Unprocessable Entity" 响应。
HTTP/1.1 422 Unprocessable Entity Content-Length: 149{ "message": "Validation Failed", "errors": [ { "resource": "Issue", "field": "title", "code": "missing_field" } ] }

所有错误对象都有资源和字段properties,所以你的客户端可以找出问题所在。
也有一个错误码,可以让你知道该字段的问题。这里是可能的校验错误码:
Error Name Description
missing 资源不存在
missing_field 针对该资源的一个必需字段没有设置。
invalid 一个字段的格式是无效的。该资源的文档应该会给你更多详细信息。
already_exists 另一个资源拥有相同的值。当资源必需拥有一些唯一键时会发生这种情况。

资源也可能发送自定义的校验错误(code 是custom 时)。自定义错误通常拥有一个message 字段来描述错误,且多数错误会包含一个documentation_url 字段 -- 指向一些可能有助于解决问题的内容。
HTTP RedirectsHTTP 重定向
API v3 会在恰当的时候使用HTTP重定向。客户端应该假定任意请求都可能导致重定向。接收到一个HTTP重定向不是错误,客户端应该跟随那个重定向。
重定向响应会有一个Location header字段,该字段包含了客户端应该重新请求的URI。
Status Code Description
301 永久重定向。
302, 307 临时重定向
也可能使用其它重定向状态码,但都会遵守HTTP 1.1 spec。
HTTP VerbsHTTP 动词
只要条件允许,API v3都会争取为每个操作使用恰当的HTTP 动词。
Verb Description
HEAD Can be issued against any resource to get just the HTTP header info.
GET 用于获取资源
POST 用于创建资源
PATCH Used for updating resources with partial JSON data. For instance, an Issue resource has title and body attributes. A PATCH request may accept one or more of the attributes to update the resource. PATCH is a relatively new and uncommon HTTP verb, so resource endpoints also accept POST requests.
PUT Used for replacing resources or collections. For PUT requests with no body attribute, be sure to set the Content-Length header to zero.用于替换资源或集合。
DELETE 用于删除资源
Authentication 认证
想要通过Github API v3认证,有三种方式。 那些需要认证的请求,在一些情况下,会返回 "404 Not Found",而不是 "403 Forbidden"。这是为了防止泄露隐私。
Basic Authentication 基本认证
curl -u "username" https://api.github.com

OAuth2 Token (sent in a header)
curl -H "Authorization: token OAUTH-TOKEN" https://api.github.com

OAuth2 Token (sent as a parameter)
curl https://api.github.com/?access_token=OAUTH-TOKEN

更多详见 more about OAuth2。注意,OAuth2 tokens 可以通过编码式获取: acquired programmatically。
OAuth2 Key/Secret
curl 'https://api.github.com/users/whatever?client_id=xxxx&client_secret=yyyy'

这个应该只能用于服务器到服务器的场景。不要泄露你的OAuth 应用的客户端secret。
Read more about unauthenticated rate limiting.
Failed login limit登陆失败限制
带有无效的credentials的认证会返回 "401 Unauthorized":
curl -i https://api.github.com -u foo:bar HTTP/1.1 401 Unauthorized{ "message": "Bad credentials", "documentation_url": "https://developer.github.com/v3" }

在短时间内探测到几个带有无效credentials的请求时,API会临时拒绝该用户的所有认证请求(哪怕带有正确的credentials),返回"403 Forbidden":
curl -i https://api.github.com -u valid_username:valid_password HTTP/1.1 403 Forbidden

{ "message": "Maximum number of login attempts exceeded. Please try again later.", "documentation_url": "https://developer.github.com/v3" }

Hypermedia 超媒体
所有的资源都可能拥有一个或多个链接到其它资源的 *_url properties。这些是用于提供显式的URLs,客户端不需要自己构建它们。非常推荐客户端使用这些。 这样做会让API未来的升级变得更简单 -- 对开发者来说。所有的URLs都预期符合 RFC 6570 URI templates。
通过使用类似于 uri_template gem的东西,你可以扩展这些模板:
>> 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"

Pagination 分页
那些返回多个items的请求,会被分页,默认每页30个items。你可以通过 "?page" parameter来指定页面。对于某些资源来说,你还可以通过"?per_page" parameter来设置一个自定义的页面size,最大100。 注意,由于技术原因,不是所有的endpoints都支持"?per_page" parameter,例如,events。
curl 'https://api.github.com/user/repos?page=2&per_page=100'

注意,page的数字从1开始,如果忽略"?page" parameter,那会返回第一页。
更多信息,见Traversing with Pagination。
Link Header 连接头
注意:调用的时候带有Link header 值而非自己构建,是很重要的。
Link header 包含分页信息:
Link: ; rel="next",; rel="last"

该例子包含了一个换行,仅是为了可读
该Link 响应头包含了一个或多个Hypermedia link relations,其中一些可能require expansion as URI templates 。
可能的 rel 值:
Name Description
next The link relation for the immediate next page of results.
last The link relation for the last page of results.
first The link relation for the first page of results.
prev The link relation for the immediate previous page of results.
Rate Limiting 速率限制
对于那些使用Basic Authentication 或者 OAuth的请求来说,最多每小时可以请求5000次。对于那些没有授权的请求来说,该限制是60。
未授权的请求是与你的IP关联的,而非发起请求的user。注意: the Search API has custom rate limit rules。
你可以检查任何API请求返回的HTTP headers,里面带有rate limit status:
curl -i https://api.github.com/users/whatever HTTP/1.1 200 OK Date: Mon, 01 Jul 2013 17:27:06 GMT Status: 200 OK X-RateLimit-Limit: 60 X-RateLimit-Remaining: 56 X-RateLimit-Reset: 1372700873

这些headers会告诉你所有有关速率限制状态的信息:
Header Name Description
X-RateLimit-Limit The maximum number of requests that the consumer is permitted to make per hour.
X-RateLimit-Remaining The number of requests remaining in the current rate limit window.
X-RateLimit-Reset The time at which the current rate limit window resets in UTC epoch seconds.

如果你需要另一种格式的时间,任何现代语言都可以做到。略。
一旦你达到了速率限制,你会收到一个错误响应:
HTTP/1.1 403 Forbidden Date: Tue, 20 Aug 2013 14:50:41 GMT Status: 403 Forbidden X-RateLimit-Limit: 60 X-RateLimit-Remaining: 0 X-RateLimit-Reset: 1377013266 { "message": "API rate limit exceeded for xxx.xxx.xxx.xxx. (But here's the good news: Authenticated requests get a higher rate limit. Check out the documentation for more details.)", "documentation_url": "https://developer.github.com/v3/#rate-limiting" }

You can also check your rate limit status without incurring an API hit.
Increasing the unauthenticated rate limit for OAuth applications为OAuth应用提高未授权速率限制
只需要将你的app的客户端ID和secret 作为query string传递过去即可:
curl -i 'https://api.github.com/users/whatever?client_id=xxxx&client_secret=yyyy' HTTP/1.1 200 OK Date: Mon, 01 Jul 2013 17:27:06 GMT Status: 200 OK X-RateLimit-Limit: 5000 X-RateLimit-Remaining: 4966 X-RateLimit-Reset: 1372700873

该方法应该仅被用于服务端到服务端的请求!
Staying within the rate limit
如果你在使用Basic Authentication或者 OAuth,当你超出了你的rate limit时,可以通过缓冲API响应、并使用 conditional requests来修复该问题。
Abuse Rate Limits 针对滥用的速率限制
为了保护GitHub的服务质量,对某些行为可能有额外的rate limit。
例如,快速地创建内容、疯狂地轮询而非使用webhooks、高并发地调用API、或者重复地请求耗费计算资源的数据,都会导致abuse rate limiting。
如果你的应用触发了该速率限制,你会收到一个信息响应:
HTTP/1.1 403 Forbidden Content-Type: application/json; charset=utf-8 Connection: close { "message": "You have triggered an abuse detection mechanism and have been temporarily blocked from content creation. Please retry your request again later.", "documentation_url": "https://developer.github.com/v3#abuse-rate-limits" }

User Agent Required
所有API请求必需包含一个有效的User-Agent header, 否则该请求会被拒绝。我们请求你使用你的GitHub用户名、或者你应用的名字作为User-Agent header value。
一个例子:
User-Agent: Awesome-Octocat-App

如果你提供了一个无效的User-Agent header,你会收到一个 "403 Forbidden" 响应:
curl -iH 'User-Agent: ' https://api.github.com/meta HTTP/1.0 403 Forbidden Connection: close Content-Type: text/html Request forbidden by administrative rules. Please make sure your request has a User-Agent header. Check https://developer.github.com for other possible causes.

Conditional requests条件请求
多数响应都会返回一个Etag header。很多响应也会返回一个 Last-Modified header。你可以使用这些headers的值来对同一个资源进行后续请求 -- 相应地使用"If-None-Match"或"If-Modified-Since" headers。如果资源没有改变,服务器会返回 "304 Not Modified"。
注意:发起条件请求、并接收到304响应,不会计入你的rate limit, 所以我们鼓励你使用它。
curl -i https://api.github.com/user HTTP/1.1 200 OK Cache-Control: private, max-age=60 ETag: "644b5b0155e6404a9cc4bd9d8b1ae730" Last-Modified: Thu, 05 Jul 2012 15:31:30 GMT Status: 200 OK Vary: Accept, Authorization, Cookie X-RateLimit-Limit: 5000 X-RateLimit-Remaining: 4996 X-RateLimit-Reset: 1372700873 curl -i https://api.github.com/user -H 'If-None-Match: "644b5b0155e6404a9cc4bd9d8b1ae730"' HTTP/1.1 304 Not Modified Cache-Control: private, max-age=60 ETag: "644b5b0155e6404a9cc4bd9d8b1ae730" Last-Modified: Thu, 05 Jul 2012 15:31:30 GMT Status: 304 Not Modified Vary: Accept, Authorization, Cookie X-RateLimit-Limit: 5000 X-RateLimit-Remaining: 4996 X-RateLimit-Reset: 1372700873 curl -i https://api.github.com/user -H "If-Modified-Since: Thu, 05 Jul 2012 15:31:30 GMT" HTTP/1.1 304 Not Modified Cache-Control: private, max-age=60 Last-Modified: Thu, 05 Jul 2012 15:31:30 GMT Status: 304 Not Modified Vary: Accept, Authorization, Cookie X-RateLimit-Limit: 5000 X-RateLimit-Remaining: 4996 X-RateLimit-Reset: 1372700873

--奇怪,怎么我这里只有Etag,内容为空?难道是因为没有登陆?
Cross Origin Resource Sharing跨域资源共享
API 支持AJAX请求从任何origin进行跨域资源共享CORS。 You can read the CORS W3C Recommendation, or this intro from the HTML 5 Security Guide.
一个示例请求,由浏览器发起:
curl -i https://api.github.com -H "Origin: http://example.com" HTTP/1.1 302 Found Access-Control-Allow-Origin: * Access-Control-Expose-Headers: ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval Access-Control-Allow-Credentials: true

这是CORS 请求:
curl -i https://api.github.com -H "Origin: http://example.com" -X OPTIONS HTTP/1.1 204 No Content Access-Control-Allow-Origin: * Access-Control-Allow-Headers: Authorization, Content-Type, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since, X-GitHub-OTP, X-Requested-With Access-Control-Allow-Methods: GET, POST, PATCH, PUT, DELETE Access-Control-Expose-Headers: ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval Access-Control-Max-Age: 86400 Access-Control-Allow-Credentials: true

JSON-P Callbacks
你可以发送一个 "?callback" parameter 到任意GET call,以让结果封装进一个JSON function。
curl https://api.github.com?callback=foo /**/foo({ "meta": { "status": 200, "X-RateLimit-Limit": "5000", "X-RateLimit-Remaining": "4966", "X-RateLimit-Reset": "1372700873", "Link": [ // pagination headers and other links ["https://api.github.com?page=2", {"rel": "next"}] ] }, "data": { // the data } })

-- 补充:所有数据都被封装进函数里啦。
你可以写一个JavaScript handler来处理该回调。下面是一个最小的示例:
Open up your browser's console.

所有的headers 都是与HTTP Headers相同的字符串,除了一个明显的例外:Link。Link headers 都是预解析好的,[url, options] tuples组成的array。
一个link看起来是这样的:
Link: ; rel="next", ; rel="foo"; bar="baz"

在回调输出里是这样的:
{ "Link": [ [ "url1", { "rel": "next" } ], [ "url2", { "rel": "foo", "bar": "baz" } ] ] }

Timezones 时区
一些请求允许指定或生成 带有时区信息的时间戳。
我们使用下面的规则,按优先级排序,来决定API调用的时区信息。
Explicitly provide an ISO 8601 timestamp with timezone information 显式地提供一个带有时区信息的ISO8601时间戳
对于那些允许指定时间戳的API调用,我们会使用指定的那个时间戳。关于如何指定时间戳,不妨看一下这个例子:this example。
Using the Time-Zone header使用Time-Zone header
根据list of names from the Olson database,使用Time-Zone header也是可以的。
curl -H "Time-Zone: Europe/Amsterdam" -X POST https://api.github.com/repos/github/linguist/contents/new_file.md

这意味着,我们会根据该header定义的timezone来生成一个时间戳。例如, Contents API 生成一个git commit时,会使用当前时间作为时间戳。该header 会决定生成时间戳的timezone。
Using the last known timezone for the user 使用用户上一次已知的时区
如果没有指定Time-Zone header,你可以进行一个认证过的请求,我们会使用用户上一次已知的时区。
上一次已知的时区会随时更新 -- 只要你浏览了GitHub网站。
UTC
【json|GitHub developer API 学习】如果上面的步骤都不起作用,我们会使用UTC作为时区来创建git commit。

    推荐阅读