我正在构建一个允许客户端存储对象的服务器。这些对象是在客户端完全构造的,对象id在对象的整个生命周期内都是永久的。

我已经定义了API,以便客户端可以使用PUT创建或修改对象:

PUT /objects/{id} HTTP/1.1
...

{json representation of the object}

{id}是对象id,所以它是Request-URI的一部分。

现在,我也在考虑允许客户端使用POST创建对象:

POST /objects/ HTTP/1.1
...

{json representation of the object, including ID}

由于POST意味着“追加”操作,我不确定在对象已经存在的情况下该做什么。我应该把请求作为修改请求,还是应该返回一些错误代码(哪个)?


当前回答

这完全取决于上下文,以及谁负责处理重复的请求(服务器或客户端或两者都有)


如果服务器只是指向副本,请查看4xx:

400坏请求——服务器不会处理一个请求,因为这是明显的客户端错误 409冲突——如果服务器不处理请求,但原因不是客户端的错 ...

对于副本的隐式处理,请参阅2XX:

200好了 201年创建 ...

如果服务器希望返回一些东西,请查看3XX:

302年发现的 303查看其他 ...

当服务器能够指向现有资源时,就意味着重定向。


如果以上还不够,那么在响应体中准备一些错误消息总是一个很好的做法。

其他回答

我会选择422不可处理实体,当请求无效时使用,但问题不在于语法或身份验证。

作为反对其他答案的论据,使用任何非4xx错误代码将暗示它不是客户端错误,而它显然是。使用非4xx错误代码来表示客户端错误完全没有意义。

It seems that 409 Conflict is the most common answer here, but, according to the spec, that implies that the resource already exists and the new data you are applying to it is incompatible with its current state. If you are sending a POST request, with, for example, a username that is already taken, it's not actually conflicting with the target resource, as the target resource (the resource you're trying to create) has not yet been posted. It's an error specifically for version control, when there is a conflict between the version of the resource stored and the version of the resource requested. It's very useful for that purpose, for example when the client has cached an old version of the resource and sends a request based on that incorrect version which would no longer be conditionally valid. "In this case, the response representation would likely contain information useful for merging the differences based on the revision history." The request to create another user with that username is just unprocessable, having nothing to do with any version conflict.

为了记录,422也是GitHub使用的状态码,当您尝试按已使用的名称创建存储库时。

在您的情况下,您可以使用409冲突

如果你想检查另一个HTTPs状态码从下面的列表

1××信息

100 Continue
101 Switching Protocols
102 Processing

2××成功

200 OK
201 Created
202 Accepted
203 Non-authoritative Information
204 No Content
205 Reset Content
206 Partial Content
207 Multi-Status
208 Already Reported
226 IM Used

3××重定向

300 Multiple Choices
301 Moved Permanently
302 Found
303 See Other
304 Not Modified
305 Use Proxy
307 Temporary Redirect
308 Permanent Redirect

4××客户端错误

400 Bad Request
401 Unauthorized
402 Payment Required
403 Forbidden
404 Not Found
405 Method Not Allowed
406 Not Acceptable
407 Proxy Authentication Required
408 Request Timeout
409 Conflict
410 Gone
411 Length Required
412 Precondition Failed
413 Payload Too Large
414 Request-URI Too Long
415 Unsupported Media Type
416 Requested Range Not Satisfiable
417 Expectation Failed
418 I’m a teapot
421 Misdirected Request
422 Unprocessable Entity
423 Locked
424 Failed Dependency
426 Upgrade Required
428 Precondition Required
429 Too Many Requests
431 Request Header Fields Too Large
444 Connection Closed Without Response
451 Unavailable For Legal Reasons
499 Client Closed Request

5××服务器错误

500 Internal Server Error
501 Not Implemented
502 Bad Gateway
503 Service Unavailable
504 Gateway Timeout
505 HTTP Version Not Supported
506 Variant Also Negotiates
507 Insufficient Storage
508 Loop Detected
510 Not Extended
511 Network Authentication Required
599 Network Connect Timeout Error

更有可能是400个坏请求

[* * 6.5.1。400错误请求**][1]

400(坏请求)状态代码表示服务器不能或 将不会处理请求由于某些东西被认为是 客户端错误(例如,格式错误的请求语法,无效的请求 消息框架,或欺骗性请求路由)。

由于请求包含重复的值(已经存在的值),因此可以将其视为客户机错误。需要在下次尝试之前更改请求。 通过考虑这些事实,我们可以得出HTTP STATUS 400错误请求的结论。

在检查重复记录的正确代码时偶然发现了这个问题。

请原谅我的无知,但我不明白为什么每个人都忽略了代码“300”,它清楚地表示“多项选择”或“模棱两可”

在我看来,这将是构建非标准或特定系统供自己使用的完美代码。我也可能是错的!

https://www.rfc-editor.org/rfc/rfc7231#section-6.4.1

我觉得你不应该这么做。

如您所知,POST用于修改集合,并用于CREATE一个新项。所以,如果你发送id(我认为这不是一个好主意),你应该修改集合,即,修改项目,但这是令人困惑的。

使用它添加一个项目,没有id。这是最好的做法。

如果您想捕获一个UNIQUE约束(而不是id),您可以响应409,就像在PUT请求中一样。但不是身份证。