HTTP Status code >= 300 Returning JSON - api

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.

Related

What response code corresponds in REST API to not finding a resource due to query params?

I found in my job that people are designing a RESTs API that has endpoints that return a single Json object (not a collection) based in query params (not path param).
For example:
/users?name=John&surname=Sparrow
with response body
{id:10, name="John", surname="Sparrow", gender="male"}
But what response code corresponds in REST API to not finding a resource due to query params?
For example:
/users?name=John&surname=Smith
(when John Smith doesn't exist).
I don't think it is a 404 error because /users endpoint exists, but I don't know if I must return a 400 error or a 200 without body (or null value) or other kind of response
Can you help me?
Thanks
What is most appropriate depends on whether an empty result list is OK or a clear failure. Whether parameters are PathParams or QueryParams has no bearing on return codes.
My general approach is that search functions such as findStuffBySearchTerms always return a successful HTTP code such as 200 and either the results or an empty list. On the other hand, fetchStuffById where I expect the entity to be found will return HTTP 404 if it is not found.
What response code corresponds in REST API to not finding a resource due to query params?
404 Not Found.
I don't think it is a 404 error because /users endpoint exists,
The resource identifier includes the query params. Which is to say, the query parameters are part of the identifier in precisely the same sense that path segments are part of the identifier.
In your request body, you can describe the circumstances of your implementation as precisely as you like.
But the audience of HTTP status codes includes general purpose components (browsers, proxies, web crawlers), for whom the response code is the primary mechanism for describing the semantics of the response:
The status-code element is a 3-digit integer code describing the result of the server's attempt to understand and satisfy the client's corresponding request. The rest of the response message is to be interpreted in light of the semantics defined for that status code. -- RFC 7230
That said, your server owns its own resources, and therefore you get to decide whether or not a resource exists, and what it's current representation looks like.
GET /users?name=Dave HTTP/1.1
200 OK
Content-Type: text/plain
Dave's not here, man.
From an HTTP/REST framing, that's a perfectly reasonable exchange; somebody asked for the latest representation of /users?name=Dave, and the latest representation is a plain text document. Absolutely fine.
The key idea here is that that HTTP status-code is metadata of the transfer of documents over a network domain.
HTTP is indifferent to the semantic meaning of the representations of resources.
That said, you should be considering in your design concerns like "what does this look like in our access logs?" If you want your operators to be able to distinguish this case from the similar case where the query parameters match information in your database, 200 vs 404 is the natural way to do that.
You'll normally prefer 404 to the other error status codes for this case because 404 indicates the response is cacheable, which is probably want you want when you are passed a request-target that has a spelling error in it somewhere.

404 vs 204 on GET, PUT, DELETE Methods

If a request want to get/delete/update to a resource which isn't exist, what do you prefer to return? 204 or 404?
Sample: api/blog/{id} can take that requests: GET, DELETE, PUT and api/blog can take GET and POST.
GET: api/blog returns list of blogs, GET: api/blog/{id} returns single blog,PUT: api/blog/{id} updates single blog and DELETE: api/blog/{id} deletes single blog.
In my opinion the distinction that matters is whether the request ends up successfully or not.
So generally in most of the cases 404 is the way to go.
I would recommend so, because the HTTP response codes are grouped by, let's say, result. source
Informational responses (100–199)
Successful responses (200–299)
Redirects (300–399)
Client errors (400–499)
Server errors (500–599)
For example, the process can be like this:
The client attempts to DELETE an entity.
The entity is not there.
This situation can be considered a client error, since deletion of nonexistent entity is being attempted
On 204 again cited from MDN:
The HTTP 204 No Content success status response code indicates that a
request has succeeded, but that the client doesn't need to navigate
away from its current page.
This might be used, for example, when implementing "save and continue
editing" functionality for a wiki site. In this case an PUT request
would be used to save the page, and the 204 No Content response would
be sent to indicate that the editor should not be replaced by some
other page.
If a request want to get/delete/update to a resource which isn't exist, what do you prefer to return? 204 or 404?
"It depends."
If the payload in the response is "a representation containing an explanation of the error situation, and whether it is a temporary or permanent condition", then I'm going to use a 4xx Client Error status code. In the case where I want to draw attention to the target-uri of the request, then I'm going to use 404 Not Found.
On the other hand, if the payload in the response is a representation of the resource, or a representation of a status of a successful action, then I'm going to use some 2xx Successful status code, usually 200 OK.
In particular, if that payload is zero bytes long, I'm normally going to use 200 with Content-Length: 0 rather than 204 No Content. 204 I reserve for those cases where I really want the user agent to stay with the same view. See also 205 Reset Content.
(Part of the lesson here - don't try to guess the meaning of a status code from the accompanying reason phrase. Read the definition.)
Whether or not a resource has a "current representation" at any given time is a "resource design" concern. It can make sense to say that this document has a representation even though we've never talked about it before. Maybe that representation is zero bytes long, maybe it has some default representation, like a government form with a bunch of blanks to be filled in later.
For example, a report of activity during some time period might have a current representation even though the time period described by the report is in the future.
404 in response to PUT or DELETE is weird.
PUT is semantically close to UPSERT, it's strange to object that you couldn't find a current representation of the resource when I'm asking you to replace it with the representation provided in the payload.
Similarly, DELETE is about decoupling a resource from its implementation. Why report that you can't do it when it has already been done?

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

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

REST API Framework. Recommended behavior for invalid querystring parameter

I am implementing a REST API Framework, and I wonder what the recommendedbehavior is, when a client submits an invalid querystring parameter.
I will illustrate what I mean with a specific example:
Say, I have an API handler on the /api/contacts/ endpoint, and the handler provides a querystring filter named id, which enables clients to select certain contacts with the provided IDs.
So, a GET or DELETE request could be /api/contacts/?id=2&id=4&id=lalalala.
Clearly, there is no such thing as a Contact with id=lalalala. In this case, what should the server behave like?
Ignore the invalid Contact with id=lalalala, and only filter the contacts on the valid ids, 2 and 4.
Respond with an error code that indicates this error. If yes, which error code should be provided?
Thanks in advance.
Edit: To clarify; The main focus of the framework I develop, is having a predictable behavior and hence response codes. For this reason, I want the clients consuming an API built on this framework, to expect the least possible surprises.
So, the question basically is: Should the API return an error in this case(and if yes, which)? Or ignore invalid filter entries, and only filter on the correct querystring parameters?
Since this is a REST call, we are talking about resources. And whenever we have a wrong filter, we should return a proper error code.
In this case i would go for 400 - bad request as the resource was found and correctly mapped (/api/contacts), but there was a problem with the query string part. Therefore a 400 and not a 404.
Would return a 404 if someone requested /api/contacts-all or some non-existant resource.
EDIT based on comments below
Agree to your comment. Ideally a 400 is a problem with the request. Going by that, you could use a 422 Unprocessable Entity. Please look at the stackoverflow link below and it talks about the same thing.
I would guess that developers around the world would be more comfortable seeing a 400 than 422 for such logical errors due to the fact that bigger companies are using 400 and not 422.
References:
Http status codes and
400 for logical error vs malformed request
Following the letter of the law, the response should be a 404 Not found. However, nobody is going to get too upset with you if you prefer to return 400 - bad request.
I would definitely return a 4XX status code though. You want the client to know that they made an error.

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.