RESTful POST 方法可以实现为幂等的吗?

Sir*_*mar 6 rest post http

我正在设计一个管理收藏夹的 RESTful API。每个收藏资源可以包含被视为收藏的一部分的两个项目的详细信息。

 HTTP POST /favorites

 {  "item1" : "ball",
    "item1-ID" : "1",
    "item2" : "bat",
    "item2-ID" : "2"
 }
Run Code Online (Sandbox Code Playgroud)

请原谅基本的 JSON 有效负载。然而,重点是 POST 的语义

上面的 POST 方法创建了一个新的收藏夹资源(包含一个球(ID 1)和一个球棒(ID 2))

我的问题是关于同一 POST 请求被发送两次时的预期行为。第一个请求将创建一个收藏夹(如预期)。发送第二个请求时会发生什么?

1) 用 409 发出错误信号

2) 用 201 表示成功

1) 不是幂等的(就像 POST 一样),而 2) 使 POST 是幂等的。

哪种方法是正确的?

D.S*_*ley 5

你以错误的方式思考这个问题。如果POST创建一个新资源,那么该资源应该有一个标识它的 URL(例如,http://.../favorite/1)。当第二个POST具有相同负载的事件发生时,是否会创建新资源?如果是这样,那么您就有两个具有唯一 URL 的独立资源。如果您的应用程序未创建新资源,则第二个资源POST将返回与第一个资源相同的 URL。

编辑

RFC7231POST的部分并没有禁止它以幂等的方式实现。但它确实提供了一些指导:

  • 如果POST创建了一个新资源,那么它应该发送一个 201(已创建)响应,其中包含标识所创建资源的Location标头
  • 如果 a 的结果POST相当于现有资源,则服务器可以通过返回带有适当Location标头的 303(参见其他)来将 UA 重定向到现有资源

POST不需要更改资源的状态。但是,GETHEAD必须幂等的。我不知道更改服务器状态所需的任何方法。

就我个人而言,POST作为实践,我将资源创建方法实现为返回 303 重定向到资源的规范 URL。我不知道 RFC 区分资源创建和重用响应的状态代码。这种方法的好处是,它不需要在响应中包含创建的资源POST,并且GET规范 URL 会将响应缓存在可能存在的任何中间缓存中。它还允许实现不检索响应并使用规范 URL(来自Location标头)的智能客户端。

就你而言,我认为我会采用 303 方法,前提是收藏夹有自己的 URL;201 如果没有的话才奇怪。如果有充分的理由区分响应中的创建和重用情况,那么创建新资源时返回 201,重用时返回 303 是合适的。我不会做的是返回 409,除非您的应用程序要求您拒绝创建已存在的资源。