在REST API设计中查找或创建成语?

时间:2014-03-12 02:16:03

标签: rest api-design

说我们有'用户'资源,对'name'有唯一约束。您将如何设计REST API来处理find-or-create(按名称)用例?我看到以下选项:

选项1:多个请求

客户端:

POST /user
{"name":"bob"}

服务器:

HTTP 409 //or something else

客户:

GET /user?name=bob

服务器:

HTTP 200 //returns existing user

选项2:一个请求,两个响应代码

客户端:

POST /user
{"name":"bob"}

服务器:

HTTP 200 //returns existing user

(如果实际创建了用户,则返回HTTP 201)

选项3:请求错误但响应数据包含冲突实体

客户端:

POST /user
{"name":"bob"}

服务器:

HTTP 409 //as in option1, since no CREATE took place
{"id": 1, "name":"bob"} //existing user returned

4 个答案:

答案 0 :(得分:11)

我相信“正确”的RESTful方式是:

GET /user?name=bob
   200: entity contains user
   404: entity does not exist, so
        POST /user { "name" : "bob" }
           303: GET /user?name=bob
                200: entity contains user

我也是Post-Redirect-Get模式的忠实粉丝,这需要服务器使用新创建的用户的uri向客户端发送重定向。然后,您在POST情况下的响应将使其实体的状态代码为200。

这意味着要经过1次或3次往返服务器。 PRG的一大优势是在发生页面重新加载时保护客户端免于重新发布,但您应该阅读更多信息以确定它是否适合您。

如果这与服务器来回过多,你可以选择2.我对https://tools.ietf.org/html/rfc2616#section-9.5的阅读并非严格的REST:

  

POST方法执行的操作可能不会产生资源   可以通过URI识别。在这种情况下,200(OK)或204   (No Content)是适当的响应状态,具体取决于是否   或不响应包括描述结果的实体。

如果你没有偏离标准,并且你担心往返,那么选项2是合理的。

答案 1 :(得分:2)

我使用的是选项2 的版本。我在创建资源时返回201,在仅检索资源时返回303 ("see other")。我之所以选择这样做,部分是因为get_or_create似乎不是一个常见的REST习惯用法,303是一个稍微不同寻常的响应代码。

答案 2 :(得分:1)

我会选择选项2,原因有两个:

首先,HTTP响应代码2xx(例如200第201)指的是与4xx不同的成功操作。因此,在发现或创建发生的两种情况下,您都有成功的操作。

其次,选项1将对服务器的请求数量加倍,这可能是重负载的性能损失。

答案 3 :(得分:0)

我相信GET请求可以:

  • 返回现有记录;或
  • 创建新记录并返回

是我在此处的答案中讨论的最有效的方法:Creating user record / profile for first time sign in

与@Cormac Mulhall和@Blake Mitchell在REST Lazy Reference Create GET or POST?中解释的那样,服务器需要在响应之前返回记录之前创建记录是不相关的

Section 9.1.1 of the HTTP specification中也对此进行了解释:

  

自然地,不可能确保服务器不会由于执行GET请求而产生副作用;实际上,一些动态资源认为该功能。 这里的重要区别是用户没有要求副作用,因此不能对它们负责。