如果 POST 成功但没有创建任何新内容,我们应该 return 什么状态码?
What status code should we return if the POST succeeds but does not result in creating anything new?
我们有一个端点,当您 post 创建新版本的资源并且 return 返回 201 和新创建资源的位置时。它根据当前版本与正在 posted 的版本(使用类似 semver 的规则集)的比较来确定新版本号。
如果您 post 的版本与现有版本相同,则不会更新任何版本号。在这种情况下我们应该 return 做什么?
- 我们可以 return 一个 201,即使我们在技术上还没有创造任何东西。
- 我不想 return 一个 409,因为它并不是真正的冲突,就像当您 post 具有相同 ID 的东西时一样。如果您 post 在现有版本略有不同的情况下编辑相同的内容,那么您会很高兴得到 201。
- 我们可以 return 一个 200,但这看起来很奇怪,并且增加了用户必须处理的响应代码
201 响应的幂等性重要吗?
有更好的建议吗?
我认为对于这种情况,幂等性不是问题,因为系统状态与初始请求中的状态不同,因为实体现在存在,所以您可以响应不同的代码。
200应该可以,就是你说的有点奇怪
我从来没有用过这个,但我读到在某些情况下你应该使用 302 重定向,以获取其他资源,在这种情况下我认为这适用,return 一个 302 并使a get 指向旧的 semver,假设你有这个实体的 get 端点。
如果操作没有创建任何内容,201
不适合:
The 201
(Created) status code indicates that the request has been fulfilled and has resulted in one or more new resources being created. [...]
如果操作成功,请参阅以下您可以考虑的一些选项:
The 200
(OK) status code indicates that the request has succeeded. The payload sent in a 200
response depends on the request method. For the methods defined by this specification, the intended meaning of the payload can be summarized as:
[...]
POST
: a representation of the status of, or results obtained from, the action;
[...]
Aside from responses to CONNECT
, a 200
response always has a payload, though an origin server MAY generate a payload body of zero length. If no payload is desired, an origin server ought to send 204
(No Content) instead. [...]
The 204
(No Content) status code indicates that the server has successfully fulfilled the request and that there is no additional content to send in the response payload body. [...]
如果操作失败:
The 400
(Bad Request) status code indicates that the server cannot will not process the request due to something that is perceived to be a client error (e.g., malformed request syntax, invalid request message framing, or deceptive request routing).
11.2. 422 Unprocessable Entity
The 422
(Unprocessable Entity) status code means the server understands the content type of the request entity (hence a 415
(Unsupported Media Type) status code is inappropriate), and the syntax of the request entity is correct (thus a 400
(Bad Request) status code is inappropriate) but was unable to process the contained instructions. For example, this error condition may occur if an XML request body contains well-formed (i.e., syntactically correct), but semantically erroneous, XML instructions.
如果 POST 的资源具有相同的版本号,但数据不同,那么 409
将是合适的。但是,如果数据与已存储的数据相同,则可能不需要 409
。通过消除过程我会说 200 OK
会很好。
We could just return a 200, but then that would seem weird, and increases the response codes that the users have to deal with
如果这是一个代价高昂的问题,请考虑消除 201
,而不是 200
。事实上,对于任何相当复杂的服务,在某些时候可能会出现 20X
(其中 X 不为 0)适用的情况。那么,这是否意味着我们在编码时考虑到每个 20X
响应,并花时间检查我们的服务是否存在 20X
优于 200
的情况?我怀疑不是。因此,除非有特定原因需要用 20X
响应,例如处理特定用例,否则只需使用 200
并减少所需的编码和文档量。我怀疑在大多数情况下,调用客户端并不关心。
最终,正确答案可能取决于使用您的 API 的客户端。如果你也在构建客户端,你可以做任何你喜欢的事情......(只是不要太疯狂。)
假设您正在编写 API 和客户端:
我的 opinion/suggestion 是...
- 如果有 IS 新版本号:
201
HTTP 状态代码将适合。
- 如果 NOT 新版本号:
200
or 204
HTTP 状态代码会很合适。
- 如果客户端知道版本号已更改或相同没有任何好处:发送
200
HTTP 状态代码。
如果你不控制客户端消费你的 API: 显然会遵从他们的期望。
您可能还希望查看 HTTP RFC 规范中的所有 HTTP Status Codes。以上状态码也link直接到相关栏目。
毫无疑问,每当您创建新资源时,都应该使用 201 Created
。
如 HTTP Method Definitions RFC 中所定义,如果操作不根据响应正文内容创建新资源,则 200 Ok
或 204 No Content
是适当的响应。
The action performed by the POST method might not result in a resource
that can be identified by a URI. In this case, either 200 (OK) or 204
(No Content) is the appropriate response status, depending on whether
or not the response includes an entity that describes the result.
If a resource has been created on the origin server, the response
SHOULD be 201 (Created) and contain an entity which describes the
status of the request and refers to the new resource, and a Location
header (see section 14.30).
现在,回到你最初的问题,即当操作成功并且没有什么可以 return 时使用什么,你应该使用 204 No Content
。此状态码专门用于请求操作成功完成但服务器无法提供额外相关信息的场景。
The 204
(No Content) status code indicates that the server has successfully fulfilled the request and that there is no additional content to send in the response payload body.
303 - See Other 怎么样?似乎很合适。我提请你注意这句话
来自 https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
的规范
This method exists primarily to allow the output of a POST-activated script to redirect the user agent to a selected resource.
这听起来像是你想对我做的。这是剩下的。
10.3.4 303 见其他
请求的响应可以在不同的 URI 下找到,应该使用该资源上的 GET 方法检索。此方法的存在主要是为了允许 POST 激活脚本的输出将用户代理重定向到选定的资源。新的 URI 不是原始请求资源的替代引用。不得缓存 303 响应,但对第二个(重定向的)请求的响应可能是可缓存的。
响应中的 Location 字段应该给出不同的 URI。除非请求方法是 HEAD,否则响应的实体应该包含一个带有指向新 URI 的超链接的简短超文本注释。
Note: Many pre-HTTP/1.1 user agents do not understand the 303
status. When interoperability with such clients is a concern, the
302 status code may be used instead, since most user agents react
to a 302 response as described here for 303
我对其他答案有些困惑,因为有些人 几乎 是对的。所以,让我们把事情弄清楚一点。如果所有请求确实都是使用 POST
方法执行的,那么在 ReSTfulness 的上下文中,它们应该修改目标服务器上的状态。否则,POST
的含义有点宽松,您可以在 RFC 7231, sec. 4.3.3.
中看到
由于请求的目的是创建资源的新版本,因此如果具有给定演示文稿的版本已经存在,则请求失败。这将取消任何 2xx-class 响应代码的资格。来自 section 6.3:
The 2xx (Successful) class of status code indicates that the client's request was successfully received, understood, and accepted.
如果您绝对愿意,可以选择 202/Accepted,这是“故意不置可否”。不过,这有点牵强,因为此状态代码用于排队处理。我会反对它。
其他人建议的 204/No Content 代码是一个糟糕的选择。不过,如果您 POST
访问了您正在更新的资源,那是绝对正确的。
因为结果既不是信息性的 (1xx) 也不是服务器的错误 (5xx)。让我们先看看 3xx class。来自 section 6.4:
The 3xx (Redirection) class of status code indicates that further action needs to be taken by the user agent in order to fulfill the request.
这里最突出的一个是 304/Not Modified。虽然听起来非常合适,但不幸的是,此代码不适用于此处。它只能在响应条件 GET
或 HEAD
请求时返回。
302/Found 听起来可能是下一个最合适的。但是,此代码用于临时重定向,这很可能不是您想要的。
正如这里所建议的那样,303/See Other 确实是一个不错的选择:
The 303 (See Other) status code indicates that the server is redirecting the user agent to a different resource [...] which is intended to provide an indirect response to the original request.
[...]
This status code is applicable to any HTTP method. It is primarily used to allow the output of a POST action to redirect the user agent to a selected resource
所有其他 3xx 代码都在处理与这里的情况几乎无关的各种形式的重定向。
最后一看,4xx-class 个状态码。来自 RFC 7231, sec. 6.5:
The 4xx (Client Error) class of status code indicates that the client seems to have erred. Except when responding to a HEAD request, the server SHOULD send a representation containing an explanation of the error situation, and whether it is a temporary or permanent condition. These status codes are applicable to any request method.
其中很少有人真正处理请求正文。其中有两个会在这里脱颖而出:一个是 400/Bad Request,它的设计过于宽泛。如果您愿意的话,它是一个包罗万象的解决方案。然而,这意味着请求正文在某种程度上是错误的(如语法错误),但事实可能并非如此。
更有趣的是409/Conflict。来自 RFC(强调我的):
The 409 (Conflict) status code indicates that the request could not be completed due to a conflict with the current state of the target resource.
定义的措辞将此代码放在接近 PUT
方法的位置,但不是唯一的。重申一下 4xx 代码的定义:
These status codes are applicable to any request method.
422/Unprocessable Entity 是一个竞争者,但它暗示了语义错误,实际上并非如此。
最终(鼓声)拼图的最后一块可以在 section 4.3.3:
中找到
If the result of processing a POST would be equivalent to a representation of an existing resource, an origin server MAY redirect the user agent to that resource by sending a 303 (See Other) response with the existing resource's identifier in the Location field.
注意“五月”。所以你真的可以在 303 和 409 之间做出选择。我觉得 409 更合适,因为很明显早期的请求引入了一个与当前不兼容的状态。 OTOH,303 可能是更礼貌的方式,更接近标准。无论哪种方式,作为您 API 的消费者,我真的很想知道我的请求是否失败了。并且没有任何影响。
201
: 创建新版本时
202
: 更新现有版本时
204
: 当请求被接受但没有处理完成时
默认,204 = 无内容
The server has fulfilled the request but does not need to return an
entity-body, and might want to return updated metainformation. The
response MAY include new or updated metainformation in the form of
entity-headers, which if present SHOULD be associated with the
requested variant.
If the client is a user agent, it SHOULD NOT change its document view
from that which caused the request to be sent. This response is
primarily intended to allow input for actions to take place without
causing a change to the user agent's active document view, although
any new or updated metainformation SHOULD be applied to the document
currently in the user agent's active view.
The 204 response MUST NOT include a message-body, and thus is always
terminated by the first empty line after the header fields.
所以它与您的需求略有不同,但我认为它最适合。
我们有一个端点,当您 post 创建新版本的资源并且 return 返回 201 和新创建资源的位置时。它根据当前版本与正在 posted 的版本(使用类似 semver 的规则集)的比较来确定新版本号。
如果您 post 的版本与现有版本相同,则不会更新任何版本号。在这种情况下我们应该 return 做什么?
- 我们可以 return 一个 201,即使我们在技术上还没有创造任何东西。
- 我不想 return 一个 409,因为它并不是真正的冲突,就像当您 post 具有相同 ID 的东西时一样。如果您 post 在现有版本略有不同的情况下编辑相同的内容,那么您会很高兴得到 201。
- 我们可以 return 一个 200,但这看起来很奇怪,并且增加了用户必须处理的响应代码
201 响应的幂等性重要吗?
有更好的建议吗?
我认为对于这种情况,幂等性不是问题,因为系统状态与初始请求中的状态不同,因为实体现在存在,所以您可以响应不同的代码。
200应该可以,就是你说的有点奇怪
我从来没有用过这个,但我读到在某些情况下你应该使用 302 重定向,以获取其他资源,在这种情况下我认为这适用,return 一个 302 并使a get 指向旧的 semver,假设你有这个实体的 get 端点。
如果操作没有创建任何内容,201
不适合:
The
201
(Created) status code indicates that the request has been fulfilled and has resulted in one or more new resources being created. [...]
如果操作成功,请参阅以下您可以考虑的一些选项:
The
200
(OK) status code indicates that the request has succeeded. The payload sent in a200
response depends on the request method. For the methods defined by this specification, the intended meaning of the payload can be summarized as:[...]
POST
: a representation of the status of, or results obtained from, the action;[...]
Aside from responses to
CONNECT
, a200
response always has a payload, though an origin server MAY generate a payload body of zero length. If no payload is desired, an origin server ought to send204
(No Content) instead. [...]
The
204
(No Content) status code indicates that the server has successfully fulfilled the request and that there is no additional content to send in the response payload body. [...]
如果操作失败:
The
400
(Bad Request) status code indicates that the server cannot will not process the request due to something that is perceived to be a client error (e.g., malformed request syntax, invalid request message framing, or deceptive request routing).
11.2. 422 Unprocessable Entity
The
422
(Unprocessable Entity) status code means the server understands the content type of the request entity (hence a415
(Unsupported Media Type) status code is inappropriate), and the syntax of the request entity is correct (thus a400
(Bad Request) status code is inappropriate) but was unable to process the contained instructions. For example, this error condition may occur if an XML request body contains well-formed (i.e., syntactically correct), but semantically erroneous, XML instructions.
如果 POST 的资源具有相同的版本号,但数据不同,那么 409
将是合适的。但是,如果数据与已存储的数据相同,则可能不需要 409
。通过消除过程我会说 200 OK
会很好。
We could just return a 200, but then that would seem weird, and increases the response codes that the users have to deal with
如果这是一个代价高昂的问题,请考虑消除 201
,而不是 200
。事实上,对于任何相当复杂的服务,在某些时候可能会出现 20X
(其中 X 不为 0)适用的情况。那么,这是否意味着我们在编码时考虑到每个 20X
响应,并花时间检查我们的服务是否存在 20X
优于 200
的情况?我怀疑不是。因此,除非有特定原因需要用 20X
响应,例如处理特定用例,否则只需使用 200
并减少所需的编码和文档量。我怀疑在大多数情况下,调用客户端并不关心。
最终,正确答案可能取决于使用您的 API 的客户端。如果你也在构建客户端,你可以做任何你喜欢的事情......(只是不要太疯狂。)
假设您正在编写 API 和客户端:
我的 opinion/suggestion 是...
- 如果有 IS 新版本号:
201
HTTP 状态代码将适合。 - 如果 NOT 新版本号:
200
or204
HTTP 状态代码会很合适。 - 如果客户端知道版本号已更改或相同没有任何好处:发送
200
HTTP 状态代码。
如果你不控制客户端消费你的 API: 显然会遵从他们的期望。
您可能还希望查看 HTTP RFC 规范中的所有 HTTP Status Codes。以上状态码也link直接到相关栏目。
毫无疑问,每当您创建新资源时,都应该使用 201 Created
。
如 HTTP Method Definitions RFC 中所定义,如果操作不根据响应正文内容创建新资源,则 200 Ok
或 204 No Content
是适当的响应。
The action performed by the POST method might not result in a resource that can be identified by a URI. In this case, either 200 (OK) or 204 (No Content) is the appropriate response status, depending on whether or not the response includes an entity that describes the result.
If a resource has been created on the origin server, the response SHOULD be 201 (Created) and contain an entity which describes the status of the request and refers to the new resource, and a Location header (see section 14.30).
现在,回到你最初的问题,即当操作成功并且没有什么可以 return 时使用什么,你应该使用 204 No Content
。此状态码专门用于请求操作成功完成但服务器无法提供额外相关信息的场景。
The
204
(No Content) status code indicates that the server has successfully fulfilled the request and that there is no additional content to send in the response payload body.
303 - See Other 怎么样?似乎很合适。我提请你注意这句话
来自 https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
This method exists primarily to allow the output of a POST-activated script to redirect the user agent to a selected resource.
这听起来像是你想对我做的。这是剩下的。
10.3.4 303 见其他
请求的响应可以在不同的 URI 下找到,应该使用该资源上的 GET 方法检索。此方法的存在主要是为了允许 POST 激活脚本的输出将用户代理重定向到选定的资源。新的 URI 不是原始请求资源的替代引用。不得缓存 303 响应,但对第二个(重定向的)请求的响应可能是可缓存的。
响应中的 Location 字段应该给出不同的 URI。除非请求方法是 HEAD,否则响应的实体应该包含一个带有指向新 URI 的超链接的简短超文本注释。
Note: Many pre-HTTP/1.1 user agents do not understand the 303
status. When interoperability with such clients is a concern, the
302 status code may be used instead, since most user agents react
to a 302 response as described here for 303
我对其他答案有些困惑,因为有些人 几乎 是对的。所以,让我们把事情弄清楚一点。如果所有请求确实都是使用 POST
方法执行的,那么在 ReSTfulness 的上下文中,它们应该修改目标服务器上的状态。否则,POST
的含义有点宽松,您可以在 RFC 7231, sec. 4.3.3.
由于请求的目的是创建资源的新版本,因此如果具有给定演示文稿的版本已经存在,则请求失败。这将取消任何 2xx-class 响应代码的资格。来自 section 6.3:
The 2xx (Successful) class of status code indicates that the client's request was successfully received, understood, and accepted.
如果您绝对愿意,可以选择 202/Accepted,这是“故意不置可否”。不过,这有点牵强,因为此状态代码用于排队处理。我会反对它。
其他人建议的 204/No Content 代码是一个糟糕的选择。不过,如果您 POST
访问了您正在更新的资源,那是绝对正确的。
因为结果既不是信息性的 (1xx) 也不是服务器的错误 (5xx)。让我们先看看 3xx class。来自 section 6.4:
The 3xx (Redirection) class of status code indicates that further action needs to be taken by the user agent in order to fulfill the request.
这里最突出的一个是 304/Not Modified。虽然听起来非常合适,但不幸的是,此代码不适用于此处。它只能在响应条件 GET
或 HEAD
请求时返回。
302/Found 听起来可能是下一个最合适的。但是,此代码用于临时重定向,这很可能不是您想要的。
正如这里所建议的那样,303/See Other 确实是一个不错的选择:
The 303 (See Other) status code indicates that the server is redirecting the user agent to a different resource [...] which is intended to provide an indirect response to the original request. [...] This status code is applicable to any HTTP method. It is primarily used to allow the output of a POST action to redirect the user agent to a selected resource
所有其他 3xx 代码都在处理与这里的情况几乎无关的各种形式的重定向。
最后一看,4xx-class 个状态码。来自 RFC 7231, sec. 6.5:
The 4xx (Client Error) class of status code indicates that the client seems to have erred. Except when responding to a HEAD request, the server SHOULD send a representation containing an explanation of the error situation, and whether it is a temporary or permanent condition. These status codes are applicable to any request method.
其中很少有人真正处理请求正文。其中有两个会在这里脱颖而出:一个是 400/Bad Request,它的设计过于宽泛。如果您愿意的话,它是一个包罗万象的解决方案。然而,这意味着请求正文在某种程度上是错误的(如语法错误),但事实可能并非如此。
更有趣的是409/Conflict。来自 RFC(强调我的):
The 409 (Conflict) status code indicates that the request could not be completed due to a conflict with the current state of the target resource.
定义的措辞将此代码放在接近 PUT
方法的位置,但不是唯一的。重申一下 4xx 代码的定义:
These status codes are applicable to any request method.
422/Unprocessable Entity 是一个竞争者,但它暗示了语义错误,实际上并非如此。
最终(鼓声)拼图的最后一块可以在 section 4.3.3:
中找到If the result of processing a POST would be equivalent to a representation of an existing resource, an origin server MAY redirect the user agent to that resource by sending a 303 (See Other) response with the existing resource's identifier in the Location field.
注意“五月”。所以你真的可以在 303 和 409 之间做出选择。我觉得 409 更合适,因为很明显早期的请求引入了一个与当前不兼容的状态。 OTOH,303 可能是更礼貌的方式,更接近标准。无论哪种方式,作为您 API 的消费者,我真的很想知道我的请求是否失败了。并且没有任何影响。
201
: 创建新版本时
202
: 更新现有版本时
204
: 当请求被接受但没有处理完成时
默认,204 = 无内容
The server has fulfilled the request but does not need to return an entity-body, and might want to return updated metainformation. The response MAY include new or updated metainformation in the form of entity-headers, which if present SHOULD be associated with the requested variant.
If the client is a user agent, it SHOULD NOT change its document view from that which caused the request to be sent. This response is primarily intended to allow input for actions to take place without causing a change to the user agent's active document view, although any new or updated metainformation SHOULD be applied to the document currently in the user agent's active view.
The 204 response MUST NOT include a message-body, and thus is always terminated by the first empty line after the header fields.
所以它与您的需求略有不同,但我认为它最适合。