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 NameDescription
missing 资源不存在
missing_field 针对该资源的一个必需字段没有设置。
invalid 一个字段的格式是无效的。该资源的文档应该会给你更多详细信息。
already_exists 另一个资源拥有相同的值。当资源必需拥有一些唯一键时会发生这种情况。

 

资源也可能发送自定义的校验错误(code 是custom 时)。自定义错误通常拥有一个message 字段来描述错误,且多数错误会包含一个documentation_url 字段 -- 指向一些可能有助于解决问题的内容。

HTTP Redirects     HTTP 重定向

API v3 会在恰当的时候使用HTTP重定向。客户端应该假定任意请求都可能导致重定向。接收到一个HTTP重定向不是错误,客户端应该跟随那个重定向。

重定向响应会有一个Location header字段,该字段包含了客户端应该重新请求的URI。

Status CodeDescription
301 永久重定向。
302, 307 临时重定向

也可能使用其它重定向状态码,但都会遵守HTTP 1.1 spec。

HTTP Verbs     HTTP 动词

只要条件允许,API v3都会争取为每个操作使用恰当的HTTP 动词。

VerbDescription
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: <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 值:

NameDescription
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 NameDescription
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来处理该回调。下面是一个最小的示例:

<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"
      }
    ]
  ]
}

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

如果上面的步骤都不起作用,我们会使用UTC作为时区来创建git commit。

posted on 2017-03-20 15:21  LarryZeal  阅读(2692)  评论(0编辑  收藏  举报

导航