What is the correct way to return a specialized HTTP response? - rest

Let's say that in my RESTful interface I require the client to include some special header, just to indicate it's an authorized client. (Trust me on this; it's a requirement of the project.) If the HTTP request contains an incorrect value in this header, the server needs to send back an HTTP response that the client can recognize that it sent an unsupported value in the header.
What's the appropriate way to send back this information using HTTP?
I could send back a 400 Bad Request response, but how do I tell the client what the problem was exactly? The obvious option is to include some message in the body of the response. But (besides issues of i18n) is it really a good idea for the client to blindly display the contents of an error message?
I could send back a 400 Bad Request response, with a proprietary special header indicating that such-and-such header had the wrong code. This has the benefit that the client can actually process what the error was (as opposed to free text in the content). So does the 400 response then become a catch-all response, with the actual error in some proprietary header? Is this a good general pattern? But that almost suggests...
I could could send back some arbitrary 4XX response that has a proprietary meaning, such as 472 Bad Foo Header Value. Microsoft seems to have gone this route at times. The obvious problem is the possibility of clashes in a future version of HTTP (or with others who have done the same thing).
I suppose I'm leaning more toward 400 Bad Request with a special header indicating the error specialization. Any thoughts or experience with this use case?

If the special header is incorrectly formatted then you could send a
400 Bad request Response indicating that the header is wrong.
However If the sole purpose of the header is authorization and you reject the header, because of invalid value, then I would opt for:
403 - Forbidden, if you want the connection to be refused
401 - Unauthorized, if the client should try to reauthenticate
In the Response phrase you can indicate the reason for refusing the connection.

Related

Relevant HTTP Status code on the Rest API

I have a scenario by passing invalid data in Path variable which is input to fetch the data from Database.As the provided data is not valid so it triggers "500 Internal Server Error" from the database as could not found the data.
and have customized HTTP Status as 404(NOT_FOUND) because data is not found.
Would like to understand,what can be the best HTTP Status code for this scenario other than 404?
HTTP is an application protocol, whose application domain is the transfer of documents over a network (Jim Webber, 2011). The status codes we use in the response are metadata from the domain of document transfer -- which is to say, we care about what the message means, not why our implementation is sending it.
The information specific to your domain, which communicates the details of the problem to the client, belongs in the message-body of the response. The status code is there so that generic components, that don't know the specifics of your domain, can "do the right thing" -- where the right thing is constrained by HTTP semantics.
Michael Kropat published flow charts that may help select the correct status code. Alternatively, you can look through the HTTP Status Code Registry, which has links to the standard that defines the semantics of each code.
Broadly speaking, if the problem is with the request, then we use some message from the 4xx message class; problems in the request are client errors. 404 specifically directs the client's attention to the target-uri.
So if the request is bad because information encoded into a path segment is incorrect, then 404 is the correct choice, because it tells the client where to look for the problem. The only reason that you would look elsewhere is if some other part of the 404 semantics were inappropriate for your circumstances.
Would like to understand what can be the best HTTP status code for this scenario other than 404?
If you are looking for something other than 404, then you could look into the more generic 400. From the RFC 7231:
6.5.1. 400 Bad Request
The 400 (Bad Request) status code indicates that the server cannot or will not process the request due to something that is perceived to be a client error (e.g., malformed request syntax, invalid request message framing, or deceptive request routing).
But bear in mind that the 404 status code itself is suitable for this situation. See the following quote from the RFC 7231:
6.5.4. 404 Not Found
The 404 (Not Found) status code indicates that the origin server did not find a current representation for the target resource or is not willing to disclose that one exists. [...]

What status code to use when a parameter is missing in the query string?

I have an endpoint that requires a parameter passed via the query string (is a GET verb).
What is the appropriated status code to give when this parameter is missing from the request? 400 is the one? or should I respond with a 404?
[GET /search?q=ok] => 200 OK
[GET /search] => 400 Bad Request? or 404 Not Found? Or 422 Unprocessable Entity? Others?
TLDR It's an HTTP 400 - Bad Request.
It's a 400 because the user did not send the Required input field.
why not 422 - because this case fits to 400. Keeping your consumers in mind, you shouldn't go to non-popular response codes if you don't really need to.
Cases for HTTP 404:
Url which the client requested is not existing in your server (usually this will be handled by your server. Application developer usually doesn't have to do anything unless you want a nice looking 404 page or for SEO reasons).
If it was a path parameter and client was looking for an entity with an id (for Example (/students/{id} and your application couldn't find such entity, you may respond with an HTTP 404.
Let's say, user send the query parameter and you did not find any items matching the query param, make no mistake, it's still an HTTP 200 with body as an empty array or so (not a 404 unlike mentioned in the previous case). Example: /customers?lastname=unobtanium
It should be 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.
404 - Not Found
The HTTP 404 Not Found Error means that the webpage you were trying to
reach could not be found on the server. It is a Client-side Error
which means that either the page has been removed or moved and the URL
was not changed accordingly, or that you typed in the URL incorrectly.
Its means server is not able to find the URI you specified. but in your case URI is valid but parameters are missing so 400 is right way to do it.
What is the appropriated status code to give when this parameter is missing from the request? 400 is the one? or should I respond with a 404?
I would argue that 404 is appropriate
The 404 (Not Found) status code indicates that the origin server did
not find a current representation for the target resource or is not
willing to disclose that one exists.
The fact that your routing implementation happens to send /search and /search?q=ok to the same handler does not mean that they are the same resource. /search identifies a resource, there's no current representation available for it, so you send a response back to the consumer explaining the problem, and put 404 in the meta data.
The big hint in the spec is this one:
A 404 response is cacheable by default
That lets us inform the client (and any intermediary components) know that this response can be reused.
It's a useful property, and it doesn't apply (out of the box) to 400 Bad Request
Heuristic: your web api should act like a document store. If you ask a document store to give you a document, but you spell the key wrong, what do you get? Some flavor of KeyNotFound exception. Same thing you would get if you asked a web server for a document in your home directory, but your spelled the file name incorrectly.
The semantics of the response indicate the right status code to use, not the implementation details.

HTTP Error Code 406

I understand that correct use of HTTP Status codes is a good indicator of correct RESTful implementation of a service. I'm not sure what code to return when the following resource is called with an invalid token to confirm creation of a new user account:
/user/confirmation POST {param is confirmation token}
By best guess is 406 Not Acceptable? But maybe it's a 200 because there is no error as such in which case the response much include information to indicate a failed confirmation?
Both 406 and 200 are unsuitable for this situation:
406 is meant for content negotiation, when the server cannot send a representation of a particular resource with the media type indicated in the Accept header of the request.
200 must be used when the operation has succeeded, what's not the case.
You could probably go for the generic 400 to express a bad request or go for 403 to indicate that the request is forbidden.
Sending the right status code is as important as proving a payload that describes the problem and helps your client to determine the cause of the error.
For reporting problems in your HTTP API, I advise you to have a look at the RFC 7807: it defines simple JSON and XML document formats to inform the client about a problem in a HTTP API and also defines the application/problem+json and application/problem+xml media types.
Michael Kropat put together a pretty useful set of diagrams to determine the most suitable status code for each situation. See the following diagram for 4xx status codes:

HTTP Status 400 Validation Versus Verification

Although RFC 7231 was intended to bring clarity, it evidently has brought ambiguity regarding status code 400. Note this SO answer and the comments. One person says 400 now includes logical, application or verification errors, another person says that 400 still is intended only for syntactic or validation errors.
6.5.1. 400 Bad Request
The 400 (Bad Request) status code indicates that the server cannot or
will not process the request due to something that is perceived to be
a client error (e.g., malformed request syntax, invalid request
message framing, or deceptive request routing).
I would like to get a more definitive answer about this. Consider two scenarios where a POST or PUT attempted to provide an e-mail address:
The e-mail found in the request failed validation (e.g. it contained "hello#gmail.com"). A 400 reply is sent.
The e-mail found in the request failed verification (e.g. another user is already using that address). A ??? reply is sent.
I want to follow RFC 7231. My reading of the 6.5.1 tells me that the verification error should receive a 409 (or 422) response. But others disagree, and claim it should now be a 400.
Does anyone have more information that would resolve this ambiguity?
200 is a fine status code to send in this situation. After all, do HTML forms get a 4xx back when you don't put in a valid post code?
Status codes are for generic consumption, not application-specific semantics. They're useful when a non-specific recipient -- e.g., a proxy, a cache, a HTTP library -- can do something interesting when it comes in.
So, 400 is to be used when there are errors stemming from client problems (such as bad request HTTP syntax). It was made more generic in 7231 because x00 status codes are the most generic of their series, and should be considered fallbacks when a more specific status code isn't defined.
You can use 400 for a validation error too, and it will be theoretically, slightly helpful in that a HTTP library knows not to repeat that request -- but it certainly isn't worth getting too concerned about if it's 200.

Best way to return error messages on REST services?

I've been looking at examples of REST API's like Netflix http://developer.netflix.com/docs/REST_API_Reference#0_59705 and Twitter and they seem to place error messages in the statusText header response instead of the responseText. We're developing an internal RESTful api and I am arguing for sending custom statusText messages and ignoring the responseText.
For the scope of our app, we're returning error 400 when the user has tried doing something they aren't supposed to, and the only error messages that will be updated in the UI for the user will be delivered with 400. I am of the belief that the message should be sent as a modified statusText but one of the engineers (who knows a bit less about REST than me) is arguing for sending it in the responseText.
What's the best way to go?
HTTP defines that you should put a descriptive error message in the response entity body, aka responseText.
statusText is not rendered or processed by any client.
I'd use the status text for the error message type, aka 400 Client Error, and the body for a description of the problem that can be rendered to the user, in whatever the format the client may be able to process.
Edit: Note that since then, a new standardised format exists to communicate in a standard fashion error details back to the client, which you can find at https://www.rfc-editor.org/rfc/rfc7807 and which I would recommend.
I think you're right, the general approach is use the existing error mechanism built into HTTP.
In general, try to map your errors to existing HTTP errors, for example if they request something they don't have permission to, return a 403 error.
If they request something that doesn't exist, return a 404.
Alex
According to the HTTP specification (rfc2616): "HTTP status codes are extensible"
However I don't think that creating new statuses for every different error message is the correct approach:
I would say choose HTTP Status appropriately (HTTP Status Code Definitions) if you can't find any category which matches your requirement create a custom one (but I'm sure you will) and put error messages in the HTTP response body.
Picking appropriate status code for your responses is extremely important as it is a key enabler of self-descriptive messages.
The entity body should be a representation of the resource's state and ideally contain hyperlinks to available next states in your application
Http Status Codes are pretty self explanatory and should be used as such. Returning 200 OK with validation errors is pretty Soap-y and misleading. Any REST Client implementation 4xx and 5xx errors go into a error block and it really depends on case to case basis if you really want to use the response body for non 2xx responses.