Best way to return error messages on REST services? - rest

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.

Related

Http Status for partial response in the case where API makes calls to multiple APIs

I have an API whose job is to aggregate resources obtained by calling multiple other APIs and then give out the aggregated response to the client. Currently even if one or more dependent API calls fail, I go ahead and aggregate response from the other dependent APIs and then give them out to the client with a 2xx status. In case all of the dependent API calls fail, I still give out a 2xx with empty list.
In case one or more dependent API calls fail, I want to give out an indication to the client. I was thinking of using the HTTP code 206. What would be the best approach to handle this scenario. Is giving out a 206 with the names of the dependent services that failed to give out a 2xx as part of a header the correct approach. If yes, what should this header be called?
I was thinking of using the HTTP code 206.
I can't promise, but that seems like a very bad idea; see RFC 7233
The 206 (Partial Content) status code indicates that the server is successfully fulfilling a range request
If the client didn't send you a range request (see RFC 7233 for the specifics), then I don't think there is any benefit in answering as if it had. General-purpose components are likely to get confused.
As for what status code to use instead: the response code, like the headers, is meta data so that general purpose components can understand what is going on and provide intelligent assistance. The details of what you are doing, that are to be understood by the bespoke client, belong in the response body.
(Analogy - on the web, the status code and the headers are for the (general purpose) browser. The response body is for the human being.)
200 OK is probably what you want to be using here; with a "representation of the status of the action" in the payload.

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:

RESTful status code for a request that cannot be satisfied because of a dependency issue

My payment endpoint which accepts a POST should deny requests when the user does not have any payment methods configured. What is the correct HTTP status code in this case?
What is the correct HTTP status code to be raised when the system itself cannot reach the state asked for by the request and another request (creating a payment method) must be completed first?
I looked at 428 Precondition Required, but that seems to have more to do with the headers than the state of the system.
I would go simply with 400 Bad Request. If you need more specific instructions or hints in the response, you can return a body, which will indicate the exact nature of the error.
You don't need to assign a specific HTTP error code to all your internal business-related error cases. Indeed this is probably not possible anyway.
The specification on 400: https://www.rfc-editor.org/rfc/rfc7231#section-6.5.1
Relevant quotes from there:
indicates that the server cannot or will not process the request due to something that is perceived to be a client error
And about the 4xx codes in general:
the server SHOULD send a representation containing an explanation of the error situation, and whether it is a temporary or permanent condition
Did you look into error 424 Failed_Dependency? I think this could bethe one you want.
See
http://www.restpatterns.org/HTTP_Status_Codes/424_-_Failed_Dependency

400 vs 422 response to POST that references an unknown entity

I'm trying to figure out what the correct status code to return on different scenarios with a "rest-like" API that I'm working on.
This example is borrowed from another question about syntax type issues in the body, but my question assumes valid syntax throughout.
Let's say I have an endpoint that allows POST'ing purchases in JSON format. It looks like this:
{
"account_number": 45645511,
"upc": "00490000486",
"price": 1.00,
"tax": 0.08
}
What is the appropriate status code if:
the account number does not exist
the account is closed or the
account identified is not the right kind of account
These are all firmly business layer issues that prevent "processing" from occuring, however, one scenario involves something that in a GET would be a 404.
Note that the account number is not in the URL, so is 404 misleading?
Let's take these one at a time. Each of these codes is a signal to your client that the server is functioning correctly, and that something must be changed in the request before it can be successfully carried out.
HTTP 400
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).
400 typically indicates a syntax error; as a user, I should look at the structure of the request before trying again.
HTTP 404
The server has not found anything matching the Request-URI. No indication is given of whether the condition is temporary or permanent. The 410 (Gone) status code SHOULD be used if the server knows, through some internally configurable mechanism, that an old resource is permanently unavailable and has no forwarding address. This status code is commonly used when the server does not wish to reveal exactly why the request has been refused, or when no other response is applicable.
404 is the standard code used when a web server can't match a url path to anything. As a client, I should look at the URL of the request before trying again.
HTTP 422
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. For example, this error condition may occur if an XML request body contains well-formed (i.e., syntactically correct), but semantically erroneous, XML instructions.
422 is generally used for content violations. As a user, I should look at the content of my request before trying again.
Now in your case, account number is an identifying number, but is not included in the URL. A 404 would signal to your user that the URL is wrong, not the payload. Stated another way, suppose your url is:
http://www.myservice.net/endpoint
A 404 would indicate to me that no service exists at /endpoint, instead of no account number. No matter what content I submit, the server will not process my request. The fix I should make then would be to look for an error in the URL, instead of the data payload. So to me a 422 would point me in the right direction, unless you begin to include the account number in the URL.
Ultimately these are design preferences, just make sure you communicate them clearly to your users.
If you consider the accounts to be part of the state of the resource (though indirectly) then you might also consider 409 since that state is in conflict with the semantics of the request.
However, 422 is gaining popularity via Ruby on Rails and Dropwizard where it is used to indicate non-syntactic issues with the body. That growing tendency represents a strong signal to a developer using the API that they need to exclude syntax and focus on the body. Developer time is usually the single largest cost your customers will ever incur, so by directing the attention of their developers you will keep them happy.
So 409 is a possible answer, though rather novel, and 422 is the more conventional approach, although obviously RoR and DropWizard are both rather new so these conventions can be said to be changing fast!
I'd say 422 is adequate in your case, but 400 isn't bad if it's consistent with the rest of your API. It's a common convention to use 400 as an umbrella error code when there's something wrong on the client side, but either the error doesn't fit a particular error code, or you don't want to use too many of them.
A 404 is definitely wrong if there's something wrong with the POST payload.
Case 1 : Account number doesn't exist.
This is a standard case for 404.
Case 2 : Account is closed.
This has do with the logic if you keep the account details when you close it.
If you donot keep the account details when the account is closed, you can give 404.
If you keep the account details after it is closed, you must be marking it (like raising some flag) (or whatever logic you have). In this case, Status code 400 with a proper message of why it is failed and possibly remediation will do.
Case 3 : Account identified is not the right kind of account.
403, as the account is not authorised for completing any purchases makes sense to me. If there is no concept like authorised account, 400 with a explanatory message will do. But I would insist to go with 403 in this case.
Actually, in this case 404 sounds good to me.

How to send response code in REST services.?

I am developing RESTful Services to CREATE operations. In my use case, it is enough to tell the clients whether the transaction is success or fail. And if fail, we need to send them back error code.
Is it possible to send only these information back without sending xml response or JSON response. If so, how to do it.
We have existing error code in 5 digits, we wont be changing this for this api. If this is not possible.
Will JSON response better than XML response.? We are accepting XML request.
Requesting your comments.
I'm going to assume this service will be called over HTTP, since that's what most people mean when they say "RESTful service."
Generally speaking, most people map "create" type functionality to POST methods (though you can also do it with PUT).
If you just need to indicate that the record was created, the answer is "None of the above" (i.e., you don't need a response body at all). Usually a 201 Created is returned with a Location header which specifies the URL of the newly-created resource. In theory, you could also return a 204 No Content since you don't need to pass anything other than the status code (though this would be more appropriate for a PUT, otherwise there is no way to communicate to the client the identifier of the newly-created resource).
For failures, usually a 400-series error is returned if the request message is bad (i.e., it's the client's fault) and a 500-series error is returned if a system error occurs when processing (i.e., it's the server's fault). If you need to convey additional information in the response body, consider returning a response that uses a media type of something like application/vnd.error which allows you to express context information about where the error occurred.