Which status code/error message to use if implied resource not found - rest

Let's say I have an endpoint /process which accepts a POST request with an object_id. My API, however, needs to access several children of the object with id object_id to work out its response.
Assuming the object is found but the children aren't, which status code and error message should I return?
Since I want to inform the end user that something went wrong as opposed to returning a blank response, I can see several options:
400 Bad Request. However, this could wrongly imply there is something wrong with the request, which there isn't.
404 Not Found. However, this could wrongly imply that the object referenced by object_id does not exist, which it does.

First, you need to determine whether the problem is client-side or server-side.
4XX errors are for bad requests. Implying that there is something wrong with the request sent from the user.
If not finding the object is due to server-side issues, I think it's better to throw a server-side error (i.e. 5XX).
Update:
Following a comment from OP, my suggestion is: 412 (Precondition Failed). Also, I think Not-Found and No-Content statuses don't fit your scenario.

I don't think there is a standard HTTP status code for this scenario. 4xx codes imply a client error, whereas 5xx is for server errors. Arguably there is nothing wrong with the request in this case, so you could return a custom 5xx status code.
Some standard status codes however come close:
409 Conflict
422 Unprocessable Entity
and even 404 Not Found

Related

Best Practices for HTTP Content Negotiation in case of Error Responses?

I have a discussion, how to implement content negotiation for error cases. I'd like to hear your opinion or experiences to deal with this topic. Please be aware that there might be APIs dealing with RFC-7807, and those who don't.
The main theses to discuss are (only concerning error responses):
The Accept-Header names the mime types that the client is able to handle in case of 2xx responses. It can be used also to decide which error response format is rendered (recommended), but this is not required. E.g. if we return a RFC-7807 problem detail, we typically use application/problem+json or application/problem+xml, although the client requested application/pdf.
The 406 response code is only for reporting back that the server is not able to create a 2xx response for the requested format(s). It would not be applicable to use when another problem occured, but the server is not able to render the error response in a client-compatible format.
In case of RFC-7807, we would mostly derive from the Accept header. If the client requests application/json, and we return application/problem+json, it's the same format, but not the same semantic and therefor has a different scheme in comparison with the 2xx response.
In case of errors, the client has to deal with response formats that it is not able to render. To minimize confusion, an OpenAPI spec for the API lists the error response formats that can be returned.
If the client sends an Accept-Header of application/problem+xml, it only prefers a special content type in case of error responses, but does not specify one for 2xx responses, so the server would use its preferred (mostly JSON).
What do you think about that?

Backend exception handling for REST app - should we return 4XX error or 200 with error mark

I am working on large-scale web app, and within the project I am developing a REST app for outside clients. I think that this question has not very much to do with the specific technology that I am using, but just in case - it's Django.
We have a convention with the development team that REST resources always return a standard JSON object of type
{'success': <value>,
'object': <value>
'error_msg': <value>,
}
along with the status (200, 201, 403, etc....)
Examples of Django implementation:
return Response({'success': true,
'object': ...,
'error_msg': ...},
status=status.HTTP_200_OK)
The success parameter is assigned true for successful deployment of the resource, and false otherwise.
Now, the entire question here lies in what should be passed in status parameter in those cases when something bad happens - appropriate 4XX code or 200 ?. The development team suggests to ALWAYS use HTTP_200_OK, simply if something bad happened, just assign false to success. The error_msg will contain detailed error message in case of exception.
So the two alternatives among which I can't choose the right one look like this
return Response({'success': false,
'object': ...,
'error_msg': 'Details regarding the error'},
status=status.HTTP_400_BAD_REQUEST)
vs:
return Response({'success': false,
'object': ...,
'error_msg': 'Details regarding the error'},
status=status.HTTP_200_OK)
(in both cases success will equal to false. So in both cases the developer will know that something went wrong by looking at success without having to check status)
However, the very existence of different error codes leaves me with unpleasant doubt that I'm missing something about WHY people have come up with different error codes. And IN WHAT SITUATIONS my project can face trouble if it always returns the same 200 status code.After reading tons of materials, I have no material explanation why specifying appropriate error status codes could outperform the approach of returning 200 status.
HTTP codes are in my opinion a great way to get information on the result of an operation for the following reasons:
They are both machine- and human-readable (at least by developers).
They are integrated in every HTTP transaction, so every library implements mechanisms to deal with them.
The repertoire of error codes is 'standardized' and everyone knows how to deal with it, and it covers a lot of common cases (the DRF framework automatically uses some of those, such as 400, 403 or 405).
By ignoring them, you are increasing the amount of work that you have to implement on your own.
Of course, they might not be enough for particular cases. Suppose you receive a 400 code when you are submitting multiple fields to your API. If you want to know which ones are invalid and why, you still need the value of your error_msg, but the 400 code still simplifies a lot of your logic, since you can filter out a lot of other reasons why the request did not succeed (403, 405...).
Regarding your question:
And IN WHAT SITUATIONS my project can face trouble if it always returns the same 200
Well, if you implement things properly, leaving all error handling to the response date, it should never cause any trouble, but as argued earlier, I feel like this increases the complexity of the task at hand.
Please note that this are just my two cents, and there might be other opinions with better arguments for the opposite case.

Should a wrong parameter passed via REST call throw an error?

I was accessing REST calls, when I passed wrong parameter to GET request it does not throw any http error. Should the design be changed to throw a http error or wrong parameter can be passed to REST call.
Example 1:(parameters are optional)
https://example.com/api/fruits?fruit=apple
Give list of all apple elements
Example 2:
https://example.com/api/fruits?abc=asb
Give list of all fruits
My question is related to example 2, should example 2 throw an error or is it behaving properly?
It's pretty common to ignore parameters that you aren't necessarily expecting. I think example 2 is behaving as it should.
I know that depending on the browser I would sometimes append an extra variable with a timestamp to make sure that the rest call wouldn't be cached. Something like:
https://example.com/api/fruits?ihateie=2342342342
If you're not explicitly doing anything with the extra parameter then I can't see the harm in allowing it.
For a GET request, the request-line is defined as follows
request-line = 'GET' SP request-target SP HTTP-version CRLF
where request-target "...identifies the target resource upon which to apply the request".
That means that the path /api/fruits, the question-mark ? and the query abc=asb are all part of the identifier.
The fact that your implementation happens to use the path to route the request to a handler, and the query to provide arguments, is an accident of your current implementation.
That leaves you with the freedom to decide that
/api/fruits?abc=asb does exist, and its current state is a list of all fruits
/api/fruits?abc=asb does exist, and its current state is an empty list
/api/fruits?abc=asb does exist, and its current state is something else
/api/fruits?abc=asb does not exist, and attempting to access its current state is an error.
My question is related to example 2, should example 2 throw an error or is it behaving properly?
If abc=asb indicates that there is some sort of error in the client, then you should return a 4xx status to indicate that.
Another way of thinking about the parameter handling is in terms of Must Ignore vs Must Understand.
As a practical matter, if I'm a consumer expecting that my filter is going to result in a small result set, and instead I end up drinking a billion unfiltered records out of a fire hose, I'm not going to be happy.
I'd recommend that in the case of a bad input you find a way to fail safely. On the web, that would probably mean a 404, with an HTML representation explaining the problem, enumerating recognized filters, maybe including a web form that helps resend the query, etc. Translate that into your API in whatever way makes sense.
But choosing to treat that as a successful request and return some representation also works, it's still REST, the web is going to web. If doing it that way gives you consumers a better experience, thereby increasing adoption and making your api more successful, then the answer is easy.

How to rename resources in an idempotent manner?

I implemented an API that renames a company as follows:
PUT /companies/A
{
"name": "B"
}
will return HTTP 301 with the Location header pointing at the company's new URI: /companies/B.
How can I make this operation idempotent with and without If-Match headers?
Without If-Match header: if a user tries to rename a non-existent company, I'd expect the server to return HTTP 404 but I can't do so because then legitimate rename operations wouldn't be idempotent (they'd return 301 the first time, and 404 on subsequent invocations). This is problematic because I want clients to be able to differentiate between a failed renames (the company doesn't exist) versus a rename that had already taken place.
With If-Match header: if the company's ETag depends on the company name, then subsequent rename operations will fail because the precondition no longer holds. Again, this makes it seem that the operation failed when in fact it already took place.
OK, this is two years old, but I'm going to answer it in case someone else stumbles upon it as I did.
The short answer is that, from HTTP point of view, renaming (moving) resources is not idempotent, and you should have used POST instead of PUT.
The long answer: PUT is a "create-or-replace" operation, defined by RFC 2616 as follows (emphasis mine):
The PUT method requests that the enclosed entity be stored under the supplied Request-URI.
RFC 7231 (which at the time this question was asked existed only as draft), puts it more clearly:
The PUT method requests that the state of the target resource be
created or replaced with the state defined by the representation
enclosed in the request message payload. A successful PUT of a given
representation would suggest that a subsequent GET on that same
target resource will result in an equivalent representation being
sent in a 200 (OK) response.
Because a successful rename will result in the resource being available at a different location, PUT is not applicable.
PS. Probably you could have made this work with PUT by including some sort of unique identifier for the company, regardless of it's name or other attributes, in the request body, that would allow you to detect previous renames and issue an appropriate redirect. Nevertheless, I think it is going against the protocol, and POST would have been more appropriate.
The PUT operation succeeds and should return a 200 or 201. Subsequent requests for the same resource should return a 301 with the appropriate response body indicating the URI of the new resource.
404 should only be for resources that truly can't be found, i.e. companies that don't exist and never have.
As noted in the protocol, idempotence doesn't mean that the call returns the same thing all the time. It means there are no side effects. Also, idempotence isn't applicable under error conditions, which anything other than 2xx (like 301) is.
I really do admire the commitment to getting it right by the spec, but as with all things, it is subject to interpretation.
I don't think a 3xx makes sense here. The PUT operation succeeded, so it should return a 2xx. 301 implies that the resource isn't where the requester thought it was.
Generally, I keep being amused about people not using MOVE when they actually want MOVE :-)

HttpClient 4.1.x - Handling protocol error with body content

I've been doing some digging with an application system utilizing HttpClient 4.1.x to handle RESTful calls under Spring.
While I've got this working great under both directly dealing with the httpclient as well as using as the transport for the RestTemplate, I've found that I have a need for something that I'm not sure was covered in execution.
The "BasicResponseHandler" treats the content response as a string and returns it provided that the response from the server is less than 300. The RESTful system I'm working with provides an XML document as part of an error response (status code >= 400). This XML response contains some information that may be of use to the client developer.
What I'd like to see if anyone has any experience dealing with this via the ResponseHandler interface. Essentially, the BasicResponseHandler will toss a ClientProtocolException in the case that there is a status >= 300. The handling AbstractHttpClient implementation will trap that exception, consume the entity silently, then re-throw the IOException (ClientProtocolException) that was thrown.
Would it be advisable to create a sub-class of ClientProtocolException to contain the additional information?
In the case of the error status, unmarshal any existing document into its respective type (if available) and then throw it thus preserving the content of the response.
Or is there another mechanism that I'm missing to handle this case?
The purpose of the ResponseHandler interface is to enable the caller to digest HTTP responses without buffering message content in memory. An extra benefit of using this interface is not having to worry about resource deallocation which is taken care of automatically by HttpClient.
In your particular case you should consider building a higher level domain object from the low level HTTP response content instead of returning a simple, unrepresentative string.
So, instead of throwing an exception, consider returning back to the caller an object consisting of the request status (success, failure, partial response, etc), and a parsed XML document or an JAXB object representing a message content.