I'm creating a RESTful API for creating users that enforces unique email addresses:
Successful POST /users: HTTP 201 Created
If I POST the same email address again, what should the response code be? Is 409 Conflict the appropriate response code?
Yes, 409 is the most appropriate response code here. Even though you are most likely returning 201 on success, you're still POSTing to a resource which is described as a collection, and POSTing a duplicate email is definitely a conflict with "the current state of the resource" as a collection. You should return a response body with a description of the problem, and hyperlinks to help resolve the problem, if possible.
I am not really satisfied with returning a 409 Conflict for an existing registered email - in my opinion, it's not a client error. So let's take a look at how some big tech companies are handling that case (at least how they are doing it in their WEB Site APIs).
Gmail (Google) returns a 200 OK and a JSON object containing a code which is indicating that the email is already registered.
Facebook is also returning a 200 OK but re-renders the content to a recovery page to give the user the option to recover his/her existing account.
Twitter is validating the existing email by an AJAX call
To another resource. The response of the email validation resource is always a 200 OK. The response contains a JSON object containing a flag to indicate if the email is already registered or not.
Amazon is doing it the same way as Facebook. Returning a 200 OK and re-rendering the content to a notification page to inform the user that the account already exists and provide him/her possibilities to take further actions like login or password change.
So all these APIs returning always a 200 OK and presenting to the client/user either additional content to recover their account or an error message which is raised by the body content of the response.
While the accepted answer is correct in showing the correct status code for the task, I want to add that you are introducing a security vulnerability.
If you return a 409 for account registration, you are just exposing a service for account enumeration.
Depends on the application, if the api is public or not, etc, you may want to return a 201 even if the account wasn't created.
+1 to Barts answer - for security reasons. Usually I would agree that 409 is a good status code for sth. that already exists. But in an environment of user accounts/authentication/authorization etc., I would tend to not exposing the existing user accounts in your database.
Of course there are other mechanisms of handling security at this place. If you do not mind to expose a little number of your accounts, you could add a behavior to your application that returns 401 or 403 on numerous 409-events from one IP.
Another option (in general) is to define a status code on your own to have a 2xx that differs from the existing standard 2xx variants. This could be an option if you do not want to handle an "already exists" as an error. However, this would be regarded as non-standard and would have the same unsafe character like a 409 in your concrete example.
I often use the (WebDAV extension) HTTP 422 Unprocessable Entity:
The request was well-formed but was unable to be followed due to semantic errors
409 => Conflict
That mean.
The request could not be completed due to a conflict.
For example, POST ContentStore Folder API cannot complete if the given file or folder name already exists in the parent location.
For registration it is required to have a code that is different from success 200 code, but not an error 4xx code.
As suggested in HTTP response code for POST when resource already exists look at 3XX:
302 Found
303 See Other
In particular
According to RFC 7231, a 303 See Other MAY be used If the result
of processing a POST would be equivalent to a representation of an
existing resource.
The concern about exposure of existing addresses to enumerating bots can be addressed by different means such as captcha.
Related
I'm developing a REST API for a system in which, for the sake of the example, exist Users and Maps. Maps can be downloaded, commented and voted by Users.
When Users download Maps a relationship is created between them. Now, when Users want to comment and vote Maps I check if that relationship exists, returning an error in case it doesn't so clients know it's missing.
Which HTTP code should I return in this case, to let clients know previous action is required?
This error case you describe sounds like it describes an bad request from the client. Thus it probably belongs in the 4xx family. Looking over the choices, 409 Conflict seems to be the best match.
http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html describes it as follows:
409 Conflict
The request could not be completed due to a conflict with the current state of the resource. This code is only allowed in situations where it is expected that the user might be able to resolve the conflict and resubmit the request. The response body SHOULD include enough information for the user to recognize the source of the conflict. Ideally, the response entity would include enough information for the user or user agent to fix the problem; however, that might not be possible and is not required.
Of course the HTTP response code alone will not be enough for clients to act upon. As the above states, the response entity should provide details about what exactly the problem is.
A 409 Conflict is probably the closest fit. It's defined thusly in RFC 2616:
The request could not be completed due to a conflict with the current
state of the resource. This code is only allowed in situations where
it is expected that the user might be able to resolve the conflict and
resubmit the request. The response body SHOULD include enough
information for the user to recognize the source of the conflict.
Ideally, the response entity would include enough information for the
user or user agent to fix the problem; however, that might not be
possible and is not required.
Some people use 400 Bad Request, but I wouldn't do that because that error signifies that the server doesn't understand what the client wants to do. It sounds like in your case, the server understands but cannot fulfill the request.
The other option is 403 Forbidden, but this is less appropriate than a 409 because it usually is used in response to not having enough privileges to view a particular resource (and the spec indicates that the request should not be repeated).
My RESTful service includes a resource representing an item ACL. To update this ACL, a client does a PUT request with the new ACL as its entity. On success, the PUT response entity contains the sanitized, canonical version of the new ACL.
In most cases, the HTTP response status code is fairly obvious. 200 on success, 403 if the user isn't permitted to edit the ACL, 400 if the new ACL is malformed, 404 if they try to set an ACL on a nonexistent item, 412 if the If-Match header doesn't match, and the like.
There is one case, however, where the correct HTTP status code isn't obvious. What if the authenticated user uses PUT to remove themselves from the ACL? We need to indicate that the request has succeeded but that they no longer have access to the resource.
I've considered returning 200 with the new ACL in the PUT entity, but this lacks any indication that they no longer have the ability to GET the resource. I've considered directly returning 403, but this doesn't indicate that the PUT was successful. I've considered returning 303 with the Location pointing back to the same resource (where a subsequent GET will give a 403), but this seems like a misuse of 303 given that the resource hasn't moved.
So what's the right REST HTTP status code for "success, and thus you no longer have access"?
200 is the appropriate response, because it indicates success (as any 2xx code implies). You may distinguish the user's lack of permission in the response (or, if you don't wish to, 204 is fine). Status codes make no contract that future requests will return the same code: a 200 response to the PUT does not mean a subsequent GET can't return 403. In general, servers should never try to tell clients what will happen if they issue a particular request. HTTP clients should almost always leap before they look and be prepared to handle almost any response code.
You should read the updated description of the PUT method in httpbis; it discusses not only the use of 200/204 but indicates on a careful reading that returning a transformed representation in immediate response to the PUT is not appropriate; instead, use an ETag or Last-Modified header to indicate whether the entity the client sent was transformed or not. If it was, the client should issue a subsequent GET rather than expecting the new representation to be sent in response to the PUT, if for no other reason than to update any caches along the way (because the response to a PUT is not cacheable). Section 6.3.1 agrees: the response to a PUT should represent the status of the action, not the resource itself. Note also that, for a new ACL, you MUST return 201, not 200.
You're confusing two semantic ideas, and trying to combine them into a single response code.
The first: That you successfully created an ACL at the location that you were attempting to. The correct semantic response (in either a RESTful or non-RESTful scenario) is a 201 Created. From the RFC: "The request has been fulfilled and resulted in a new resource being created."
The second: That the user who executed the PUT does not have access to this resource any more. This is a transient idea - what if the ACL is updated, or something changes before the next request? The idea that a user does not have access to a resource of any kind (and this includes an ACL resource) only matters for the scope of that request. Before the next request is executed, something could change. On a single request where a user does not have access to something you should return a 403 Forbidden.
Your PUT method should return a 201. If the client is worried about whether it has access any more, it should make a subsequent request to determine it's status.
You might want to take a look at HTTP response code "204 No Content" (http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html), indicating that the "server has fulfilled the request [to be removed from the ACL] but does not need to return an entity-body, and might want to return updated metainformation" (here, as a result of the successful removal). Although you're not allowed to return a message body with 204, you can return entity headers indicating changes to the user's access to the resource. I got the idea from Amazon S3 - they return a 204 on a successful DELETE request (http://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectDELETE.html), which seems to resemble your situation since by removing yourself from an ACL, you've blocked access to that resource in the future.
Very interesting question :-) This is why I love REST, sometimes it might get you crazy. Reading w3 http status code definitions I would choose (this of course is just my humble opinion) one of those:
202 Accepted - since this mean "well yes I got your request, I will process it but come back later and see what happens" - and when the user comes back later she'll get a 403(which should be expected behavior)
205 Reset Content - "Yep, I understood you want to remove yourself please make a new request, when you come back you'll get 403"
On the other hand (just popped-up in my mind), why should you introduce a separate logic and differentiate that case and not using 200 ? Is this rest going to be used from some client application that has an UI? And the user of the rest should show a pop-up to the end-user "Are you sure you want to remove yourself from the ACL?" well here the case can be handled if your rest returns 200 and just show a pop-up "Are you sure you want to remove user with name from the ACL?", no need to differentiate the two cases. If this rest will be used for some service-to-service communication(i.e. invoked only from another program) again why should you differentiate the cases here the program wouldn't care which user will be removed from the ACL.
Hope that helps.
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.
In my RESTful API client might try to post information that is already in the database, this is not an error, rather something client can ignore, maybe notify the user about already existing dublicate.
Now i'm returning 409 Conflict and already existing object in the response body. I feel that it's incorrect because:
The request could not be completed due to a conflict with the current
state of the resource. This code is only allowed in situations where
it is expected that the user might be able to resolve the conflict and
resubmit the request. The response body SHOULD include enough
information for the user to recognize the source of the conflict.
Ideally, the response entity would include enough information for the
user or user agent to fix the problem; however, that might not be
possible and is not required.
via restpatterns.org
and in general, it seems, that 409 is more associated with PUT.
What is the correct response in this case? Could it be 303 See Other and Location header?
I'm not sure there is a correct answer. We are returning a 409 with a message that it's a duplicate resource. We also include hypermedia to that resource. It seems you could also use a 400 - Bad Request but that seemed too generic. I could see the 303 also working. I wanted to indicate that there was an error so we went with the 409.
I'm developing a REST api. To simplify my question, I have an API that allows people to create a new blogpost.
Blogposts can live in categories, and categories are specified by a category id. If a user would supply a category-id that doesn't exist, which HTTP error code is the most appropriate?
404 for Not Found seems bad, so I went with 400 Bad Request for now. Is there a better one?
I assume you are responding to a PUT or POST request on your blog post resource.
I would go with the 400 since the resource you are accessing with the URI is found. The blog post could have been modified if the request content had been correct.
Since this is the content of the sent query that is wrong and not the actual URI of the resource, I would stick with the 400 error.
If however, you are adding the blog post to the category by either PUTting or POSTing to the category, then you can return a 404 Not found.
I agree with Vincent in that, of the available defined status codes, 400 is the best. The client should know whether or not a category id is valid at the time it submits the request, and is therefore providing bad request content to the server.
With regard to some of the other answers provided:
404 Not Found - This is not the correct status to use, since the resource you're sending the request to actually was found - it was just a referenced resource within the provided resource that was not found.
406 Not Acceptable - This status is, like Evert commented, used with the Accept headers; see section 10.4.7 of RFC2616:
The resource identified by the request is only capable of generating
response entities which have content characteristics not acceptable
according to the accept headers sent in the request.
409 Conflict - This status is intended for conflicting states of resources, typically due to modifications to the resource perhaps by another channel or thread. The RFC (section 10.4.10) gives an example:
...if versioning were being used and the entity being PUT
included changes to a resource which conflict with those made by an
earlier (third-party) request, the server might use the 409 response
to indicate that it can't complete the request
HTTP does provide an alternative to 400 - if fitting, you can create your own 4XX status for this situation. In section 6.1.1 of the RFC:
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.
You could therefore define your own custom "430 - Referenced Resource Not Found" or something similar. HTTP-abiding clients should, if this status is unknown to them, treat it as a 400, but if clients are being coded specifically to the API, they should be able to handle it as a 430 and work with it appropriately.
What about 409 Conflict which is an application specific violation of a rule? In this this case the category ID of the Blog post must already exist. When you return the 409 conflict reply identify what the user can do to correct the situation so they can retry the POST/PUT.
I think 404 Not Found is the most appropriate response - consider the client has tried to access a category which doesn't exist, so the perfect answer is "I can't find that category!"
404 has a very specific and commonly-used meaning, which is that the URL could not be found. Furthermore, some browsers will use their own 404 error page, confusing things more.
See http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
I would recommend "406 Not Acceptable
The resource identified by the request is only capable of generating response entities which have content characteristics not acceptable according to the accept headers sent in the request."
400 isn't bad, though.