Appropriate HTTP response code when previous action is required - http

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).

Related

HTTP Status Code for Captcha

Sometimes (when the resource is requested too often) I'm intercepting the presentation of a (HTML) resource with a captcha. The interception doesn't produce any redirection. It happens all at the same URI.
I'm wondering now which HTTP status code would fit most for these requirements:
it should fit semantically.
Google should understand that this interception is a temporary condition which should not affect the existing resource in its index.
A web browser will display the response body with the captcha.
These are my candidates which I identified so far:
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.
This sounds perfect. The conflict state comes from those clients requesting the resource too often. The response also includes enough information to identify the source of conflict plus resolve it.
503 Service Unavailable
The server is currently unable to handle the request due to a temporary overloading […] of the server. The implication is that this is a temporary condition […]. If known, the length of the delay MAY be indicated in a Retry-After header.
This sounds moderately appropriate. I might even know the length of delay and provide such header. But I'm missing here the point that the user can resolve the problem. Furthermore the scope is too broad (overloaded server vs. overloaded resource).
You may want to consider status code 429, defined in https://www.rfc-editor.org/rfc/rfc6585#section-4.
For me 422 is somewhat accurate for this case:
response status code indicates that the server understands the content
type of the request entity, and the syntax of the request entity is
correct, but it was unable to process the contained instructions.
FWIW I'm using 498.
wikipedia:
Code 498 indicates an expired or otherwise invalid token.
498 Invalid Token (Esri)
Returned by ArcGIS for Server. Code 498 indicates an expired or otherwise invalid token.[74]

What is an appropriate HTTP response code for a file that already exists?

I was wondering what is the right HTTP ERROR CODE for someone that is trying to:
PUT /newfile.txt HTTP/1.1
Host: myhost
What's the appropriate error code if the client wants to add a file that already exists? I don't know what to use ... I have looked at the RFC but can't find a appropriate code.
It’s a rarely used response code, but it seems to me that 409 Conflict might be the best fit for your needs:
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.
Conflicts are most likely to occur in response to a PUT request. For
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. In this case, the
response entity would likely contain a list of the differences between
the two versions in a format defined by the response Content-Type.
409 Conflict or another from the 400 range like 428 will work, but arguably, you break REST if you don't allow the client to overwrite a resource using a PUT.
PUT should be idempotent, and if you refuse to execute the command based on what's already there, idempotence is broken.

REST HTTP status code for "success, and thus you no longer have access"

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.

What's a proper response status code to REST POST request when duplicate is found?

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.

Which HTTP response code for "This email is already registered"?

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.

Resources