ChatGPT解决这个技术问题 Extra ChatGPT

HTTP status code for a partial successful request

I have an application that sends messages to users. In a post request a XML string is transferred that consists of all the users that should receive that particular message. If any of the users in the list do not exist I give the list of missing users back to the client for further evaluation.

Now I'm asking myself what would be the proper status code for the application saying that the request was accepted but there were things that couldn't be done.

The problem would be avoided if it weren't allowed to include missing users in the list. Then the sending attempt would just get an 4xx error. But there is no point in forming the API this way. On the other hand I could consider the error condition to be purely application specific. But sending a 200 just does not feel right. And it would be nice to give the client a hint when to look deeply in the error response. e.g. to avoid sending messages to that users over and over


K
Kylar

I've dealt with a very similar issue. In this case, I returned a

207 Multi-Status

Now, this isn't strict HTTP, it's part of the WebDAV extension, so if you don't have control over the client too, then this isn't good for you. If you do, you could do something like so:

   <?xml version="1.0" encoding="utf-8" ?>
   <D:multistatus xmlns:D='DAV:'>
     <D:response>
       <D:user>user-123</D:user>
       <D:status>success</D:status>
     </D:response>
     <D:response>
       <D:user>user-789</D:user>
       <D:status>failure</D:status>
     </D:response>
   </D:multistatus>

But again, this is an HTTP extension, and you need to have control of the client as well.


I thought about using this but I wasn't quite comfortable with it. Thanks!
The nice thing about it is that you can return as much or little of pertinent data as you want - which is especially useful for mixed-data sets, i.e.: where some fail and some pass.
I understand. I'm just trying to avoid an extra level of status handling (which is not nice IMHO). Most of my code works with HTTP ones. And I think my described use case will do fine without.
You can always send a body back - send a 200 with a JSON response or whatever you want in it to determine which ones were successful.
Yes, I know. But if you return a body you need to parse it. And at that moment you introduce a second layer of application logic handling. This raises complexity and you need a good reason to do it then.
A
Arne

I've had the same problem, and I've ended up using two different solutions:

HTTP return code 202: Accepted, indicating that the request was ok, but there's no guarantee everything actually went as it should.

Return a normal 200 in the response, but include a list of what didn't pan out in the response body.

The second one usually works best, but the first one is great if you're lazy or use a queue for processing.


Isn't 202 referring more to something like queueing?
Yes, @Sinaesthetic. From the most recent HTTP 1.1 spec, "(...) the request has been accepted for processing, but the processing has not been completed". So, for partial success, 202 is not appropriate.
IMO 200 explicitly allows for partial success as the intended meaning of the payload is specified as status for POST, PUT and DELETE. tools.ietf.org/html/rfc7231#section-6.3.1 Status 202 is successful start of an asynchronous call whose result is not known yet. Similar to getting a promise/future. The response should tell how to get the actual result or at least monitor the status.
C
Cem Kalyoncu

I needed the same issue and after reading a bit of the documentation, the best solution to this problem seems to respond with an non-standard 2xx response. A generic client will treat this as success but a specific client can understand what has happened. You may also support this with custom headers in form X-failed: thispart code. You probably should include what is the problem with the operation as text so that generic clients will be able to display nature of what has happened. Here is what I have done where a file is uploaded but the processing cannot be done at this moment:

HTTP/1.1 210 Partial success
X-failed: processing
X-reason: server busy

File has been uploaded, however, the task associated with the 
file has not started as the server is busy. Re-request processing
at a later time.

Y
Yusuf

What about using 206 Partial Content. I know 206 is more about ranges, but what if it could indicate a partially successfully request?


MDN states as follows: "The HTTP 206 Partial Content success status response code indicates that the request has succeeded and has the body contains the requested ranges of data, as described in the Range header of the request." As far as I understand, 206 Partial Content is strictly for requests with a content range.
The W3C RFC doc also specifies that 206 is for a partially-fulfilled GET request, not POST. The server has fulfilled the partial GET request for the resource. The request MUST have included a Range header field (section 14.35) indicating the desired range, and MAY have included an If-Range header field (section 14.27) to make the request conditional. w3.org/Protocols/rfc2616/rfc2616-sec10.html
A
AVee

The HyperText Transfer Protocol deals with the transmission side of things. It doesn't have error codes to deal with application level errors.

Returning 200 is the right thing to do here. As far as HTTP is concerned the request was received properly, handled properly and you're sending the response back. So, on the HTTP level everything is OK. Any errors or warnings related to the application which running on top of http should be inside the response. Doing so will also prevent some nasty issues you might run into with proxy servers which might not handle certain responses the way you expect.


HTTP is an application level protocol. You cannot put it simply on transport and application level. If you think about OSI then HTTP is on layers 5-7. HTTP is somewhat different. Most of the headers and return codes are indeed application specific. The codes just depend on the information given in the HTTP protocol entities and not on custom application format things. Regarding the 200 I would say that your definition is purely wrong if it is applied to verbs not being POST. But POST changes the game a little bit and in this context your assumption "handled properly" is not sure, either
Stricly speaking OSI considers HTTP a application level protocol and when talking to a 'normal' webserver this is true. But in your case you are running your own protocol on top of HTTP, like lots of applications do these days. In that type of usage HTTP just provides the transport. (Your application is sending messages to users, not transferring hypertext...)
Just to be clear. HTTP in a REST way is resource centric. In this context 200 means identity (the resource you specified) instead of 3xx which points in direction of the identity. Using POST turns the resource URI into a processing URI and there error codes need to cope with that. The context shifts a bit and the defintion of things get a bit blurry or at least hard to understand
The context shift also means there are no suitable error codes, since the protocol was never designed with that context in mind ;-) I also think you should be careful with using error codes since proxy servers tend to run with them replacing your response with a custom error page, this can be a real PITA.
Anyway, thanks for answering my question. I just discovered stackoverflow is bad chat client :)