我正在编写一个基于 HTTP 的 API,我遇到用户指定资源的情况,如果该资源尚不存在,则服务器会创建它。get_or_create
它基本上建立在 Django 的方法之上。
在这种情况下,最惯用/正确的 HTTP 方法是什么?
我怀疑这POST
是正确的。但是,我不完全确定。虽然这似乎GET
是不正确的,因为它不应该有任何副作用。
我正在编写一个基于 HTTP 的 API,我遇到用户指定资源的情况,如果该资源尚不存在,则服务器会创建它。get_or_create
它基本上建立在 Django 的方法之上。
在这种情况下,最惯用/正确的 HTTP 方法是什么?
我怀疑这POST
是正确的。但是,我不完全确定。虽然这似乎GET
是不正确的,因为它不应该有任何副作用。
我会用GET
这个。对该端点的重复调用将返回相同的资源,因此它仍然是幂等的。
请求表达了GET
用户不产生任何副作用的意图。当然,服务器上总会有副作用,例如日志条目,但这里的重要区别是用户是否要求副作用。
如果您对在服务器上创建资源的请求使用推荐的响应进行响应,那么远离GET
表面的另一个原因。201 Created
下一个请求将导致不同的状态响应,200 OK
因此它不能像GET
请求的通常情况那样被缓存。
相反,我建议使用PUT
定义为
PUT 方法请求将封闭的实体存储在提供的 Request-URI 下。如果 Request-URI 引用了一个已经存在的资源,封闭的实体应该被认为是在源服务器上的一个修改版本。如果 Request-URI 不指向现有资源,并且该 URI 能够被请求用户代理定义为新资源,则源服务器可以使用该 URI 创建资源。
如果创建了新资源,源服务器必须通过 201 (Created) 响应通知用户代理。如果修改了现有资源,则应发送 200(OK)或 204(No Content)响应代码以指示请求成功完成。如果无法使用 Request-URI 创建或修改资源,则应给出反映问题性质的适当错误响应。
在上面的表格中,它应该被认为是一个“创建或更新”动作。
要实现纯粹的“获取或创建”,您可以做出响应,409 Conflict
以防更新导致不同的状态。
但是,特别是如果您正在寻找幂等性,您可能会发现“创建或更新”语义实际上可能比“获取或创建”更合适。不过,这在很大程度上取决于用例。
我不会GET
用于创建资源,因为您永远不知道是否某个机器人(如搜索引擎机器人)正在跟踪列出GET
的调用,这会创建大量无用的资源。