为什么 GitHub API 使用 PUT 请求为存储库加注星标?

Why does the GitHub API use a PUT request for starring a repository?

我正在开发自己的 REST API 并且正在寻找其他成熟的 API 以了解他们在需要公开某种可以执行的操作时会做什么在资源上。其中一项是在 GitHub 上为 repository/gist 加注星标和取消加注星标的功能。根据 their docs,您可以用 PUT /gists/{gist_id}/star 加星,用 DELETE /gists/{gist_id}/star 取消加星。

这是文档对 HTTP verbs 的描述:

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?

我能看到的一个原因是星星“存在”,而这些路线只是在星星上切换某种“活动”属性。所以你不会使用 POST 因为你不是在创建星星,只是切换它的活动 属性.

编辑:这也只是基于我如何实现这样的东西的猜测,因为他们的文档有点稀疏。

So I guess I'm just wondering why PUT instead of POST?

PUT,在 HTTP 中,比 POST 对其语义有更严格的限制——例如,PUT 的语义是幂等的,当你通过一个不可靠的网络; PUT告诉你,如果服务器收到一份以上的请求消息,不会有问题。

(这很像问为什么用 GET 而不是 POST,只不过区别更小)

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


https://docs.github.com/en/rest/overview/resources-in-the-rest-api#http-verbs does NOT define the semantics of the HTTP methods. The standardized definitions of GET, PUT, POST and so on are in RFC 7231.

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

The PUT method requests that the state of the target resource be created or replaced with the state defined by the representation enclosed in the request message payload.

“使您的文档副本看起来像我的副本”是向服务器传达信息的一种非常合理的方式,并且该消息的含义根本不取决于服务器是否已经知道关于处理请求时的文档。


I am developing my own REST API

一定要查看 Jim Webber's 2011 talk,我认为这对阐明基于网络的 API 如何“应该”工作大有帮助。