I have seen a lot applications using REST API returning a status code inside theirs response bodies, although the HTTP response returns the status code just fine. Is there any reason to put the status code also in the body of the response?
Some APIs return a 200 for all requests, even erroneous ones, and put a status code in the response body. This status code might mimic HTTP status codes, but doesn't have to. One could start numbering your response statuses from 1 for all anyone cares.
Other APIs return appropriate HTTP status codes, and indeed, put the same status code in the response. That's just a waste of bandwidth and brain cells, and a cause for lots of head scratching. It's unnecessary. Except...
It might be useful for some kinds of client libraries. When a client application uses a library that abstracts away all the HTTP stuff, it can just return an object to the programmer that contains all information about the response.
Something like:
{
"status": 200,
"data": {
"foo" : "bar"
}
}
And:
{
"status": 401,
"data": null,
"message": "You are not authorized."
}
This way the library author can chuck the HTTP status code into the object's status property, and the caller doesn't have to deal with exception handling.
But then still there's no reason for the API to respond with it both in HTTP status code and response.
Is there any reason to put the status code also in the body of the response?
Yes, in the sense that the status-line is HTTP metadata, describing the semantics of the response message. Like other HTTP metadata, it's not really designed for use by the end client.
Consider the web experience - the browser gets to see the HTTP response message, and can act on it. But what information do you want to share with the user? In cases where you wanted the user to be aware of the HTTP status code, you would include it in the HTML representation also.
Problem Details for HTTP APIs includes an optional status field in its schema to surface that information for the client.
Related
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.
I was wondering if it is acceptable/common to have a server return a JSON response along side a 3xx or 4xx response?
The reason I ask this is because I do return a JSON response with more details regarding the error, but it seems the engine I am using doesn't agree with what I am doing. I would like to make sure my approach is acceptable before submitting a PR.
It's perfectly fine for 3xx or 4xx responses to have body entities, sometimes it's even required.
For example, for 300 Multiple Choices:
Unless it was a HEAD request, the response SHOULD include an entity containing a list of resource characteristics and location(s) from which the user or user agent can choose the one most appropriate.
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
With your error responses you need to pass some attribute that indicates the error type anyway. So that makes HTTP status code redundant or sometimes even inaccurate.
Any real benefit here, and why it shouldn't just be 200?
Assuming we're talking about a RESTful API:
Because if you return an error message with a HTTP Status Code of 200, the client will assume his request was successful, and maybe not read the response body at all.
If the status code is 200, the client will not be looking for an error message in the response body.
An HTTP status code is not redundant. Pretty much in the same way a book's index is not redundant. First you look at the index for a topic you want to read on, and then you flip to that page and read more on that topic. Similarly, the client first reads the status code to know what happened, and then reads the response body to find out more about it.
I am building a wrapper for a 3rd party api (email suite) inside of a web application, accessible internally and via an own api. The methods take, for example, an email-address and a subscription list as a parameter and return a result code.
So basically I want to:
Define status codes to display different states of success/failure.
For example successes:
new contact created
new contact created AND optin mail sent
new contact created AND coupon sent
existing contact subscribed
existing contact subscribed AND coupon sent
and so on..
All of these cases are basically the category 2xx OK, but have to trigger different user feedback messages, that's why I'm unhappy with using the HTTP status codes. Using pure HTTP status codes doesn't give feedback detailed enough and defining a) additional status codes or b) completely custom status codes feels so random.
So, what is the best practice to go here?
This answer suggests that I should always use the standard HTTP status codes and if they do not apply, my design is wrong. How would I distinguish the difference, without using additional logic and api calls on the client side?
The purpose of HTTP status codes is to convey the status of the HTTP operation - was it successful, unauthorized, pending, misconfigured, whatever. In all your described cases, the requested operation was successful - everything went as planned. So the most likely status code is 200 OK or 201 CREATED for ALL those cases.
Additional domain-specific statuses should not be forcefully hammered into HTTP statuses. Just return an additional field in your response. For example:
POST http://www.example.com/users
{
name : "The User",
email : "email#theuser.com"
}
Response would contain:
201 CREATED
{
status : "Optin mail sent",
timestamp : "...",
...
}
This keeps a cleaner separation of concerns and improves extensibility.
How would I distinguish the difference, without using additional logic and api calls on the client side?
Use meaningful response bodies. The status code is just that. You don't want to create a new HTTP status code for each new combination of results.
So for your first three scenarios:
HTTP/1.1 201 Created
...
{
contact_created: "true",
optin_mail_sent: "true",
coupon_sent: "true",
}
You need some display logic on the client side any way (e.g. from 254 ContactYesOptInNoCouponYes to the appropriate notifications), so the response body seems the most sensible and extensible way possible.