GitHub developer API 学习
官网地址:https://developer.github.com/v3/
目录
默认,所有请求都接收v3版本的API。我们推荐显式地请求 -- 通过Accept header。
Accept: application/vnd.github.v3+json
所有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。
很多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发起一个GET请求,以获取该endpoint的所有categories -- API支持的:
curl https://api.github.com
当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 字段 -- 指向一些可能有助于解决问题的内容。
API v3 会在恰当的时候使用HTTP重定向。客户端应该假定任意请求都可能导致重定向。接收到一个HTTP重定向不是错误,客户端应该跟随那个重定向。
重定向响应会有一个Location header字段,该字段包含了客户端应该重新请求的URI。
Status Code | Description |
---|---|
301 |
永久重定向。 |
302 , 307 |
临时重定向 |
也可能使用其它重定向状态码,但都会遵守HTTP 1.1 spec。
只要条件允许,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 |
用于删除资源 |
想要通过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" }
所有的资源都可能拥有一个或多个链接到其它资源的 *_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"
那些返回多个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: <https://api.github.com/user/repos?page=3&per_page=100>; rel="next", <https://api.github.com/user/repos?page=50&per_page=100>; 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. |
对于那些使用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" }
所有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.
多数响应都会返回一个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
你可以发送一个 "?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来处理该回调。下面是一个最小的示例:
<html> <head> <script type="text/javascript"> function foo(response) { var meta = response.meta; var data = response.data; console.log(meta); console.log(data); } var script = document.createElement('script'); script.src = 'https://api.github.com?callback=foo'; document.getElementsByTagName('head')[0].appendChild(script); </script> </head> <body> <p>Open up your browser's console.</p> </body> </html>
所有的headers 都是与HTTP Headers相同的字符串,除了一个明显的例外:Link。Link headers 都是预解析好的,[url, options] tuples组成的array。
一个link看起来是这样的:
Link: <url1>; rel="next", <url2>; rel="foo"; bar="baz"
在回调输出里是这样的:
{ "Link": [ [ "url1", { "rel": "next" } ], [ "url2", { "rel": "foo", "bar": "baz" } ] ] }
一些请求允许指定或生成 带有时区信息的时间戳。
我们使用下面的规则,按优先级排序,来决定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
如果上面的步骤都不起作用,我们会使用UTC作为时区来创建git commit。
posted on 2017-03-20 15:21 LarryZeal 阅读(2714) 评论(0) 编辑 收藏 举报