how to handle errors and status codes with server side events - http

I am wondering about how to handle errors when sending data via SSE
Regular HTTP
If for example I want to fetch a User record by id via an http endpoint /users/:id and I encounter a non existing user I would respond with status code 404 and the client would handle it.
SSE
Now I'm wondering how this would look like for SSE. Let's say my endpoint is /users and takes a list of ids ?user_ids=[1, 2, 3]. The endpoint should find each record and send the results one by one. If the user with id 3 cannot be found, what is the protocol to convey this to the client?

I found a post on the subject:
207 is a correct answer. The interesting fact is in the comments
The nice thing about it is that you can return as much or little of pertinent data as you want
I use :
200 with a partial content (mentionned here) as your data is partial yet pertinent
Do not use:
202 does mean the request is being processed.

Related

Correct status code to send for an HTTP POST request where the given ID does not match an object in the database

Lets say I have an endpoint in my API with the following URL:
www.example.com/api/create-order-for-restaurant/
Now, in my POST request, I send the following data:
{
"restaurant_id": 43,
"order": {...}
}
Lets say a restaurant with the id 43 does not exist in my database. What should be the appropriate HTTP status code that should be sent back to the client?
Im confused if I should be sending back 404 or 500.
This is a client error because the client specified a restaurant_id that didn't exist.
The default code for any client error is 400, and it would be fitting here too.
There are slightly more specific client error codes that might work well for this case, but it's not terribly important unless there is something a client can do with this information.
422 - could be considered correct. The JSON is parsable, it just contains invalid information.
409 - could be considered correct, if the client can create the restaurant with that specific id first. I assume that the server controls id's, so for that reason it's probably not right here.
So 400, 422 is fine. 500 is not. 500 implies that there's a server-side problem, but as far as I can tell you are describing a situation where the client used an incorrect restaurant_id.

How to name my custom HTTP codes?

We're building a backend with a number of APIs. What should be the ideal range of HTTP codes that I should be using?
I've gone through https://en.wikipedia.org/wiki/List_of_HTTP_status_codes and they give a list such as:
1xx Informational
2xx Success
3xx Redirection
4xx Client Error
5xx Server Error
But since I want to implement my own status codes for various purposes such as missing email, I want to name the response accordingly.
So, according to me, a missing email response should trigger a 4xx response as it's a client error. What I'm trying to understand is that should I look for the first open slot such as #419 or should I begin to number the HTTP codes after #451?
You shouldn't use any custom codes at all - they might conflict with future standardization.
If you think you have a use case for a new code that is of general use, propose it in the right place (the HTTP Working Group).
If you just need something specific to your application, use a 400 (in this case), and provide additional information in the response body.

Status code 400 or 200 for error on another micro-service

My application is currently composed of two micro-services :
A. Subscription micro-service
B. Payment micro-service
It also uses another external service:
C. Payment provider
If a user tries to create a subscription with an invalid card number (let's say his card is blocked) the C. service will return me a 200 with a "success" parameter to "false" (I don't handle this service so I can't do anything about that).
Now my question is, what status code should the Payment (B) and Subscription (A) micro-services return ?
I'm not sure if it's a 4** or a 200 (with a success parameter) because the request itself is ok, the input format is ok (even if the data inside it is invalid).
In this situation, a 200 clearly isn't correct, because the request wasn't successful.
My recommendation in such cases is HTTP 422 Unprocessable Entity, which is defined in WebDAV but widely understood, and indicates that the request was syntactically valid but had semantic errors that prevented successful processing.
If the request is syntactically correct - e.g. card number matches some given regex, but is invalid in an another way it definitely should not be 400 Bad Request. This is simply not a bad request.
It also should no return any of 2XX codes since this codes are dedicated for successful responses and - as you set in body success = false is not a request that was processed successfully.
The code that will be the most appropriate will be 409 Conflict along with clear message describing the problem. It indicates that request failed, clarifies why and states explicitly that after correcting the request it can be resubmitted.

Should I use HTTP 4xx to indicate HTML form errors?

I just spent 20 minutes debugging some (django) unit tests. I was testing a view POST, and I was expecting a 302 return code, after which I asserted a bunch database entities were as expected. Turns out a recently merged commit had added a new form field, and my tests were failing because I wasn't including the correct form data.
The problem is that the tests were failing because the HTTP return code was 200, not 302, and I could only work out the problem by printing out the response HTTP and looking through it. Aside from the irritation of having to look through HTML to work out the problem, a 200 seems like the wrong code for a POST that doesn't get processed. A 4xx (client error) seems more appropriate. In addition, it would have made debugging the test a cinch, as the response code would have pointed me straight at the problem.
I've read about using 422 (Unprocessable Entity) as a possible return code within REST APIs, but can't find any evidence of using it within HTML views / handlers.
My question is - is anyone else doing this, and if not, why not?
[UPDATE 1]
Just to clarify, this question relates to HTML forms, and not an API.
It is also a question about HTTP response codes per se - not Django. That just happens to be what I'm using. I have removed the django tag.
[UPDATE 2]
Some further clarification, with W3C references (http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html):
10.2 Successful 2xx
This class of status code indicates that the client's request was successfully received, understood, and accepted.
10.4 Client Error 4xx
The 4xx class of status code is intended for cases in which the client seems to have erred.
10.4.1 400 Bad Request
The request could not be understood by the server due to malformed syntax.
And from https://www.rfc-editor.org/rfc/rfc4918#page-78
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.
[UPDATE 3]
Digging in to it, 422 is a WebDAV extension[1], which may explain its obscurity. That said, since Twitter use 420 for their own purposes, I think I'll just whatever I want. But it will begin with a 4.
[UPDATE 4]
Notes on the use of custom response codes, and how they should be treated (if unrecognised), from HTTP 1.1 specification (https://www.rfc-editor.org/rfc/rfc2616#section-6.1.1):
HTTP status codes are extensible. HTTP applications are not required
to understand the meaning of all registered status codes, though such
understanding is obviously desirable. However, applications MUST
understand the class of any status code, as indicated by the first
digit, and treat any unrecognized response as being equivalent to the
x00 status code of that class, with the exception that an
unrecognized response MUST NOT be cached. For example, if an
unrecognized status code of 431 is received by the client, it can
safely assume that there was something wrong with its request and
treat the response as if it had received a 400 status code. In such
cases, user agents SHOULD present to the user the entity returned
with the response, since that entity is likely to include human-
readable information which will explain the unusual status.
[1] https://www.rfc-editor.org/rfc/rfc4918
You are right that 200 is wrong if the outcome is not success.
I'd also argue that a success-with-redirect-to-result-page should be 303, not 302.
4xx is correct for client error. 422 seems right to me. In any case, don't invent new 4xx codes without registering them through IANA.
It's obvious that some form POST requests should result in a 4xx HTTP error (e.g. wrong URL, lacking an expected field, failing to send an auth cookie), but mistyping passwords or accidentally omitting required fields are extremely common and expected occurrences in an application.
It doesn't seem clear from any spec that every form invalidation problem must constitute an HTTP error.
I guess my intuition is that, if a server sends a client a form, and the client promptly replies with a correctly-formed POST request to that form with all expected fields, a common business logic violation shouldn't be an HTTP error.
The situation seems even less defined if a client-side script is using HTTP as a transport mechanism. E.g. if a JSON-RPC requests sends form details, the server-side function is successfully called and the response returned to the caller, seems like a 200 success.
Anecdotally: Logging in with bad credentials yields a 200 from Facebook, Google, and Wikipedia, and a 204 from Amazon.
Ideally the IETF would clear this up with an RFC, maybe adding an HTTP error code for "the operation was not performed due to a form invalidation failure" or expanding the definition of 422 to cover this.
There doesn't appear to be an accepted answer, which to be honest, is a bit surprising. Form validation is such a cornerstone of web development that the fact that there is no response code to illustrate a validation failure seems like a missed opportunity. Particularly given the proliferation of automated testing. It doesn't seem practical to test the response by examining the HTML content for an error message rather than just testing the response code.
I stick by my assertion in the question that 200 is the wrong response code for a request that fails business rules - and that 302 is also inappropriate. (If a form fails validation, then it should not have updated any state on the server, is therefore idempotent, and there is no need to use the PRG pattern to prevent users from resubmitting the form. Let them.)
So, given that there isn't an 'approved' method, I'm currently testing (literally) with my own - 421. I will report back if we run into any issues with using non-standard HTTP status codes.
If there are no updates to this answer, then we're using it in production, it works, and you could do the same.
The POST returns 200 if you do not redirect.
The 302 is not sent automatically in headers after POST request, so you have to send the header (https://docs.djangoproject.com/en/dev/ref/request-response/#django.http.HttpResponse) manually and the code does not relay on data of the form.
The reason of the redirection back to the form (or whatever) with code 302 is to disallow browser to send the data repeatedly on refresh or history browsing.

POST/Redirect/GET (PRG) vs. meaningful 2xx response codes

Since the POST request in a POST/Redirect/GET (PRG) pattern returns a redirect (303 See Other) status code on success, is it at all possible to inform the client of the specific flavour of success they are to enjoy (eg. OK, Created, Accepted, etc.) as well as any appropriate headers (eg. Location for a 201 Created, which might conflict with that of the redirect)?
Might it be appropriate, for example, to make the redirected GET respond with the proper response code & headers that would be expected from the POST response?
The HTTP 1.1 spec says:
This method [303] exists primarily to allow the output of a POST-activated script to redirect the user agent to a selected resource.
But doesn't offer any insight into the loss of the more usual status code and headers.
Edit - An example:
A client sends POST request to /orders which creates a new resource at /orders/1.
If the server sends a 201 Created status with location: /orders/1, an automated client will be happy because it knows the resource was created, and it know where it is, but a human using a web browser will be unhappy, because they get the page /orders again, and if they refresh it they're going to send another order, which is unlikely to be what they want.
If the server sends a 303 See Other status with location: /orders/1 the human will be taken to their order, informed of its existence and state and will not be in danger of repeating it by accident. The automated client, though, won't be told explicitly of the resource's creation, it'll have to infer creation based on the location header. Furthermore, if the 303 redirects somewhere else (eg. /users/someusername/orders) the human may be well accomodated, but the automated client is left drastically uninformed.
My suggestion was to send 201 Created as the response to the redirected get request on the new resource, but the more I think about it, the less I like it (could be tricky to ensure only the creator receives the 201 and it shouldn't appear that the GET request created the resource).
What's the optimal response in this situation?
Send human-targetted information in the response body as HTML. Don't differentiate on the User-Agent header; if you also need to send bodies to machines, differentiate based upon the Accept request header.
If you have control over the web server, how about differentiating between the Agent header ?
Fill it in something only you know of (a GUID or other pseudo-random thing) and present that one to the webserver from the automated client. Then have the webserver response with 201 / 303 accordingly.

Resources