极客学院团队出品 · 更新于 2018-11-28 11:00:42

整合者的最佳做法

想要和 GitHub 平台进行整合?应该是一个不错的选择。这个指南会帮助您创建一个应用程序,并让其在确保能可靠地和API交互的前提下为您的用户提供最好的体验。

  • 保证 GitHub 发送过来的负载的安全
  • 能够异步的情况下就不要同步
  • 当回应 GitHub 时使用恰当的 HTTP 状态码
  • 对用户提供尽可能多的信息
  • 跟随所有 API 发来的重定向请求
  • 不要手动解析 URL
  • 处理速率限制
  • 处理 API 错误

保证 GitHub 发送过来的负载的安全

保全从 GitHub 发送过来的负载是非常重要的。虽然没有个人信息(例如密码)会通过负载传输,但泄露任何信息终归是不好的。因为有的信息可能会被认为敏感,例如发出 commit 的用户邮箱或者私有存储库的名称。

你能通过以下三个步骤来保全来自 GitHub 的负载:

  1. 确保你的接收用服务器是工作在 HTTPS 连接上。默认情况下,每次发送负载时 GitHub 都会验证 SSL 证书。

  2. 你可以将我们发送 hook 时使用的 IP 地址添加进服务器的白名单。你还可以通过 /meta 端点来查找我们使用的地址,以确保你一直在使用我们正确的地址。

  3. 提供一个秘密令牌来确保负载的确来自于 GitHub。使用秘密令牌,你就能确保你的服务器接收的任何数据都是绝对来自于 GitHub。理想情况下,你应该为每个不同的用户提供不同的秘密令牌,这样即使一个令牌沦陷,也不至于影响到其他用户。

能够异步的情况下就不要同步

GitHub 期望整合服务器能在接收到 webhook 负载的 30 秒内回应。如果你的服务没能在时限内发出回应,GitHub会终止连接,所发送的负载也将会丢失。

因为我们不可能预计你的服务会需要多长时间完成,你应该将所有“真正的工作”放在后台处理。Resque (用于 Ruby), RQ (用于 Python), 或 RabbitMQ (用于 Java) 都是一些用来控制后台工作的排队和处理的库。

请注意即使有后台工作正在运行,GitHub 仍然期望你的服务器能在 30 秒内回应。你的服务器只需要通过发送某种形式的回应确认它接收了负载。所以你的服务能否在最短时间内验证负载是至关重要的,这样才能即时准确地向 GitHub 回应你的服务器是否还要继续处理该次请求。

当回应 GitHub 时使用恰当的 HTTP 状态码

每一个 webhook 都有它自己的“最近投递”区域,里面写明了一次部署是否成功。

最近投递视图

你应该利用正确的 HTTP 状态码来告知用户。你能使用类似 201202 来确认一些不会被处理的负载(例如,一个由不是默认分支发送过来的负载)。保留错误码 500 用于灾难性错误。

对用户提供尽可能多的信息

用户可以调查你发回给 GitHub 的服务器回应。请确保你的信息清晰并且有用。

查看一个负载回应

跟随所有 API 发来的重定向请求

当一个资源被移动时,GitHub 会很明确地通过一个重定向状态码告诉你。所以你应该跟随这些重定向请求。每一个重定向回应都会将 Location 头设定为目标 URI。如果你的收到一个重定向请求,你最好将新的 URI 更新到你的代码,以防你再次要求一个我们随时可能移除的已经过时的路径。

我们提供了一个 HTTP 状态码列表,以供您设计应用程序时参考来执行重定向请求。

不要手动解析 URL

经常地,API 的回应包含 URL 形式的数据。例如,当你请求一个存储库,我们会发送一个叫做 clone_url 的键,附带你能用来复制存储库的 URL。

为了您的应用程序稳定性,你不应该试图解析这些数据,或者尝试猜测和构建未来 URL 的格式。一旦我们决定更改 URL 格式,你的程序就很可能失效。

举例来说,当处理分页结果时,自行构建那些结尾带有 ?page=<number> 的 URL 经常显得十分诱人。请抵制这种诱惑。遍历分页页面指南会提供一些信息让你安全可靠地跟随分页结果。

处理速率限制

GitHub API 速率限制确保了这套 API 对所有人都同样快速和可用。

如果你达到速率限制,那么你应该暂时停止发送请求,并且在你被允许的前提下稍后再试。不遵循这个规则将导致您的应用程序被禁止。

你能随时检查你的速率限制状况。查询你的速率限制状况所产生的通讯不会负面影响你的速率限制状况。

处理 API 错误

尽管代码也许从未引入任何 bug,但你还是可能会在访问 API 的过程中遇到一连串的错误。

比起忽略接踵而来的 4xx5xx 状态码,你更应该确保你在用正确的方式和 API 进行互动。举个例子,如果一个端点请求一个字符串,然而你却返回了一个数字值,那必然会导致 5xx 验证错误,该调用也不会成功。相似的,尝试访问一个未经授权的甚至不存在的端点会引起 4xx 错误。

故意忽略多次验证错误会导致您的应用程序因为滥用被暂停。