首页 > 解决方案 > 为什么 GitHub API 使用 PUT 请求为存储库加注星标?

问题描述

我正在开发自己的 REST API,并正在寻找其他完善的 API,以了解它们在需要公开可以对资源执行的某种操作时会做什么。出现的一个功能是在 GitHub 上为存储库/gist 加注星标和取消星标。根据他们的文档,您可以使用PUT /gists/{gist_id}/star加星标和取消星标DELETE /gists/{gist_id}/star

这就是文档关于HTTP 动词的说法:

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  Used for deleting resources.

删除对我来说很有意义,但为什么会PUT使用呢?既然可以GET /gists/{gist_id}/star,那么“明星”似乎是某种功能资源。所以我想我只是想知道为什么PUT而不是POST

标签: restgithub-apiputapi-design

解决方案


所以我想我只是想知道为什么 PUT 而不是 POST?

在 HTTP 中,PUT 对其语义的限制比 POST 更严格——例如,PUT 的语义是幂等的,当您通过不可靠的网络发送请求时,这很方便;PUT 告诉您,如果服务器收到多个请求消息副本,则不会有问题。

(这很像问为什么 GET 而不是 POST,只是差异更小)

这就是为什么当您有一个简单的远程创作用例(例如将文档上传到文档存储)时,PUT 是最佳选择——因为它允许通用客户端(如浏览器)做有用的事情而无需额外的带外信息。


https://docs.github.com/en/rest/overview/resources-in-the-rest-api#http-verbs没有定义 HTTP 方法的语义。GET、PUT、POST 等的标准化定义在RFC 7231中。

如果您查看 RFC,您会发现HTTP PUT的语义也涵盖了“创建”:

PUT 方法请求创建目标资源的状态或将其替换为请求消息有效负载中包含的表示定义的状态。

“让你的这个文件看起来像我的副本”是一种向服务器传达信息的完全合理的方式,并且该消息的含义完全不取决于服务器是否已经知道该文件时请求被处理。


我正在开发自己的 REST API

请务必查看Jim Webber 的 2011 年演讲,我认为这对于阐明基于 Web 的 API “应该”如何工作大有帮助。


推荐阅读