what should be HTTP status code if resource is not available for requested action? - api

I am developing a RESTful API. I am confused about setting HTTP status code in this particular scenario. I am not sure what status code should I (server) return.
Let's say my app has a follow user functionality, if I am already following a user and again I send follow request for the same user id then in this case what should be the HTTP status code from server. The status code will be followed by an error message saying something like: "already following the user."
Similar scenario can be considered for unfollow user functionality, if I am not following an user "A", still I send request to unfollow user "A", then what HTTP status code should server return with error message something like "not following user to unfollow"
Certainly 200 response code doesn't seem to be appropriate to me here? or does it?
Please forgive me if I have posted the question at wrong stack exchange site, I posted it in stackoverflow site just because it is related to REST APIs.
EDIT
From client side user needs to send POST request to the URL:
http://www.myserver.com/api/follow/10
along with other necessary parameters ( like API keys, proper headers, etc) which are used for authentication before serving the requests at server side.
similar URL for unfollow action is:
http://www.myserver.com/api/unfollow/10
Right now, I am sending HTTP status code 200 in response if the client sends follow request, let's say, for user id 10 even if he/she is already following the user with id 10. In this case,along with status code (200) I am sending message similar to "already following the user"
Somehow I feel this is not convincing as no resource is created/updated it should return the error message with proper status code something other than 200, may be one from 4XX, not sure.

422 Unprocessable Entity
422 seems to be the proper HTTP status code in this use case.
The description of 422 says:
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.

The answer depends on your API. You're describing the API in terms of "follow user X" or "unfollow user Y". That makes me think you might be approaching your API design in an RPC style rather than focusing on resources.
If your API uses REST including the HATEOAS principle, then error codes from the 4xx range may be appropriate (but I would recommend against it in this case, see below). In very short: HATEOAS means that your resources provide links to possible "actions". You can read more about it here: http://restcookbook.com/Basics/hateoas/
Apart from that, it seems a good idea to design your API "fault tolerant", i.e. expect the same request sent multiple times (e.g. because users are impatient and click again and again, or the browser crashed and is restarted and reopens all previous tabs, or...).
My personal opinion and recommendation is the following:
follow user X: Your implementation should check if it needs to add the new follower or not. Regardless, if the user is already following or not, send back HTTP status 201 (created) and add the "Location" HTTP header pointing at the resource.
unfollow user X: Your implementation should check if it needs to delete the follower or not. Regardless, if the user is already removed from the followers or not, send back HTTP status 200 (OK).
The general idea is, if a client requests something to be a certain way and that is already the case, the server has two options: Either it responds to the client "The result you wish is already in place. Therefore your request is invalid." or the server can respond "The result you wish is already in place. You have everything you need.".
Going for the second option makes the API more tolerant and helps with idempotency (see http://restcookbook.com/HTTP%20Methods/idempotency/).

I think djlauk's answer covers a lot, but I want to give a little different approach and add some information:
Do not use verbs in the URI
I would not use POST on /follow/ respectively /unfollow/ URIs because this is not very RESTful see this SO question: Why does including an action verb in the URI in a REST implementation violate the protocol? and escpacially this SO answer: How to create REST URLs without verbs?
Do use the correct HTTP verbs for the actions
What you want to do is a creation of an entity ("follow") so for that you can use the HTTP verbs POST or PUT and afterwards the deletion of that entity ("unfollow") where DELETE would be the right fit.
My approach for your API:
I would do the following:
(The first two examples are just for explaining the structure, you don't have to implement them if you don't need them.)
This does get you the user "robert":
GET http://www.myserver.com/api/users/robert/
response: #200
This does get you the users "robert" is following:
GET http://www.myserver.com/api/users/robert/following/
response: #200
And this is how you let "robert" follow "rahul":
PUT http://www.myserver.com/api/users/robert/following/rahul
response: #200
If you send this request again you get the same response:#200 because PUT is idempotent and this is how it should behave (see (2))
When you now want to let "robert" unfollow "rahul" you send:
DELETE http://www.myserver.com/api/users/robert/following/rahul
response: #200
If you send the DELETE request again you get a little different response a #404 , but this is HTTP standard and the clients should understand this.
For the regular answer codes of HTTP methods I can also recommend this source: restapitutorial.com

I would use some of the following:
System.Net.HttpStatusCode.ServiceUnavailable;
System.Net.HttpStatusCode.MethodNotAllowed;
System.Net.HttpStatusCode.BadRequest;
Better if it is one of the first two.

Certainly 200 response code will not work in this situation.
following are the groups in HTTP Status Code:
1xx Informational
2xx Success
3xx Redirection
4xx Client Error
5xx Server Error
Certainly you need to use 4xx.
I think for the condition that you have described here, you can use any of the following:
405 Method Not Allowed
A request was made of a resource using a request method not supported by that resource; for example, using GET on a form which requires data to be presented via POST, or using PUT on a read-only resource.
400 Bad Request
The server cannot or will not process the request due to something that is perceived to be a client error
409 Conflict
Indicates that the request could not be processed because of conflict in the request, such as an edit conflict in the case of multiple updates.
More details are available here:
http://en.wikipedia.org/wiki/List_of_HTTP_status_codes

Related

Correct http status for invalid config in request body?

I am having trouble picking the correct HTTP Status for when an API is receives an attribute that maps additional data in the system but that additional data is not found. I was initially thinking 422 since it describes the use case but sounds like it is reserved for WebDAV. Then I was thinking maybe a 404 but I mentally associate that to a URL being incorrect. The other option was using error code 200 and have a failure message.
Example: the key nvdaKey is not a key configuration that the system knows about.
POST: pgpTool.com/encrypt
{
"message": "my secret message",
"keyConfigName": "nvdaKey"
}
The IANA HTTP Status Code Registry currently lists HTTP Semantics as the authoritative reference for status code 422
The 422 (Unprocessable Content) status code indicates that the server
understands the content type of the request content (hence a 415
(Unsupported Media Type) status code is inappropriate), and the
syntax of the request content is correct, but was unable to process
the contained instructions.
So if you think that's a winner, go for it.
403 Forbidden is also an option ("I understood your request, but I refuse to fulfill it").
Status codes are meta data in the transfer of documents over a network domain; the intended audience is general purpose HTTP components (browsers, caches, proxies....) Clients are supposed to be getting the semantics of the message from the body (in just the same way we expect humans reading the web to learn of errors by reading the returned web page, rather than by reading HTTP headers).
So apart from some purely mechanical concerns (caching, interpretation of headers) it is not necessarily critical that you produce precisely the right status code, so long as you get the class (Client Error / 4xx) correct.
Do note that a client that doesn't recognize a 422 is expected to treat the response as though it were a 400.

HTTP status code for an expired confirmation code

I have an endpoint in my REST API that sends a code the user received per email to verify the email address.
What status code should I better use to return that this code has expired?
Is it 401, 410 or 498?
I would recommend using status code 498 if you wanna show the user that their authorization code is invalid
or use 410 to show that the link is invalid
Edit: Note that 498 is an unofficial status code
HTTP status codes are metadata of the transfer of documents over a network domain. They are a token that instructs general purpose HTTP clients how to interpret the response (especially the other meta data fields).
When considering an unassigned status code (like 498), you want to keep in mind that general purpose components that don't recognize the code are going to treat the response as though it had the x00 response code of the same class (so 498 --> 400, 298 --> 200, and so on).
That said, if your expected context includes clients that do understand the semantics of 498, then this is less of a concern.
I have an endpoint in my REST API that sends a code the user received per email to verify the email address.
What status code should I better use to return that this code has expired?
You can make a good case for either 200 or 410, I think.
In either case, the important thing to the client is going to be the representation in the payload, which is going to be some kind of "so sorry" message and maybe hypermedia controls to restart the process.
The 410 response is primarily intended to assist the task of web maintenance by notifying the recipient that the resource is intentionally unavailable and that the server owners desire that remote links to that resource be removed.
So that could be a reasonable choice, given that you don't particularly want this URI to be reused
If the URL reads something like https://website.com/confirm-email/1738-65b9-7a39-8d1c I would use http status code 410.

Is the difference between GET v POST in convention or by design?

Background:
Looking at some links like these below, I noticed two unique sets of descriptions for GET versus POST.
One description states that the difference is in how the information is sent: GET sends that information through the URL whereas POST sends that information through the HTTP request body.
Another description states that the difference is in which way that
information is sent: GET sends information to the server whereas POST
requests information from the server.
I find these descriptions to be lacking for the following reasons:
What if I want to get something from the server (GET) but I am sending a large amount of data first (eg. 50MB of text) so I would need to send it in the HTTP request body (POST). Would it be OK to use POST to get something from the server?
What if I don't want sensitive information to be stored in the URL, is it OK to instead use POST everytime?
The jquery GET function has the same method signature as the jquery POST function (see documentation), specifically it can also send data as A plain object or string that is sent to the server with the request, which I interpret as being added to the HTTP request body. If data for GET can be sent via the HTTP request body, then to me, this contradicts most of these sites that claim that as one of the differentiating descriptions of POST vs GET.
Nothing's to stop me from creating API endpoints which are GET but behave like POST (or PUT, or DELETE or PATCH)
Question:
Is the lack of strict descriptions because of my poor understanding, because of the ad hoc development process for HTTP/Ajax or is it something else entirely?
Supporting Links:
HTTP Request Methods
GET vs. POST
GET vs POST: Key Difference between HTTP Methods
jQuery - AJAX get() and post() Methods

Choose appropriate HTTP status codes in controversial situations or introduce subcodes?

I am developing iOS application running against a remote server, having another developer behind it. The project and an API draft we are writing are in initial phase.
The problem we are faced with is that we are not satisfied with existing amount of conventional status codes described by HTTP/REST specifications: there are cases where we are uncertain about what code to pick up.
Examples to provide minimal context:
Server-side validation errors. Fx. Client-side validations are ok, but server API has recently been changed slightly, so a server should return something indicating that it is exactly the validation problem.
An attempt to register user that already exists. SO topics do not provide any precise point on that.
A user is registered, and tries to log in without having the password confirmation procedure accomplished.
Two obvious approaches we see here:
Use fx 400 error for the cases when an appropriate conventional status code could not be found. This will lead us to parsing error text messages from JSON responses. Obviously, this approach will introduce superfluous complication in a client-side code.
Create our own sub-codes system and rely on it in our code. This one involves too much artificial conventions, which will lead us towards becoming too opinionated and arbitrary.
Feeling that the number of such cases is going to grow, we are thinking about an introduction of custom sub-codes in JSON responses our server should give (i.e. choose the second approach).
What I'm asking here:
What are the recommended approaches, strategies, even glues or hacks for these kinds of situations?
What are pros-cons of moving away from strictly following REST/HTTP conventions for status codes?
Thanks!
For validation problems, I use 422 Unprocessable Entity (WebDAV; RFC 4918)
The request was well-formed but was unable to be followed due to semantic errors. This is because the request did not fail because of malformed syntax, but because of semantics.
Then in order to communicate you just need to decide on your errors format, so for situation 1 if there is a required field you might return a 422 with the following.
{
"field": ["required"]
}
I would treat number two as a validation problem, since really it is a validation problem on username, so a 422 with the following.
{
"username": ["conflict"]
}
Number three I would treat as a 403 Forbidden because passing an authorization header will not help and will be forbidden until they do something other than pass credentials.
You could do something like oauth2 does and return a human readable description, a constant that people can code against that further clarifies the error and a uri for more information.
{
"error": "unfinished_registration",
"error_description": "Must finish the user registration process",
"error_uri": "http://yourdocumentation.com"
}
Note: you will find that people disagree on what http codes map to what situation and if 422 should be used since is part of the WebDAV extensions, and that is fine, the most important thing you can do is document what the codes mean and be consistent rather than being perfect with what they mean.
There's no such thing as "sub-codes" in HTTP (Microsoft IIS is clearly violating the spec, and should be flogged).
If there's an appropriate status code, use it; don't say "this status code means that in my application" because that's losing the value of generic status codes; you might as well design your own protocol.
After that, if you need to refine the semantics of the status code, use headers and/or the body.
For the use cases you have described, you could use these error codes:
1) 400 Bad Request
The request could not be understood by the server due to malformed syntax. The client SHOULD NOT repeat the request without modifications.
2) 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.
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.
3) 401 Not Authorized
The request requires user authentication. The response MUST include a WWW-Authenticate header field (section 14.47) containing a challenge applicable to the requested resource. The client MAY repeat the request with a suitable Authorization header field (section 14.8). If the request already included Authorization credentials, then the 401 response indicates that authorization has been refused for those credentials. If the 401 response contains the same challenge as the prior response, and the user agent has already attempted authentication at least once, then the user SHOULD be presented the entity that was given in the response, since that entity might include relevant diagnostic information. HTTP access authentication is explained in "HTTP Authentication: Basic and Digest Access Authentication" [43].
For any other use case that you have, it varies. I would probably go with number 2 if there is truly no standard way of encoding specific errors.

What is the proper HTTP response code for request without mandatory fields

Consider simple case where user is deleting a post. This is simple HTTP DELETE/POST request with one mandatory field, post_id.
What should server do if post_id is not provided?
Apparently, user should never encounter this behaviour, so let's be puristic.
My first take would be 400 bad request, but spec says
The request could not be understood by the server due to malformed syntax. The client SHOULD NOT repeat the request without modifications.
and I'd say missing field is OK from syntax/http POV, it's application domain-specific semantic requirement.
200 OK with explanations is bad, 500 feels weird as this is request problem.
Thoughs?
400 is the correct response.
400 is not restricted to a malformed syntax from an HTTP point of view. Missing a mandatory argument is an error in the syntax defined by the application and thus a "Bad Request"
EDIT
At first it seems strange that there is no separate return code for this, but the return codes are designed to differentiate in what actions the client should take. A 400 error code means that the client should change the POST data or query string to the format defined by the application. Hence it is appropriate for this case.
In a REST scenario, the resource to be deleted should be identified by the URL, so the ID of the resource should be a part of that URL in order to properly identify it. Once that assumption is correct, then the URL either is identifying a different resource fr deletion, or it isn't (which would give a 404)
In the general case of a missing parameter, however, I often use a 403 Forbidden error. The reasoning is that the request was understood, but I'm not going to do as asked (because things are wrong). The response entity explains what is wrong, so if the response is an HTML page, the error messages are in the page. If it's a JSON or XML response, the error information is in there.
From rfc2616:
10.4.4 403 Forbidden
The server understood the request, but is refusing to fulfill it.
Authorization will not help and the request SHOULD NOT be repeated.
If the request method was not HEAD and the server wishes to make
public why the request has not been fulfilled, it SHOULD describe the
reason for the refusal in the entity. If the server does not wish to
make this information available to the client, the status code 404
(Not Found) can be used instead.