Bruno Penteado
Bruno Penteado

Reputation: 2274

404 status code and its double meaning on a common-almost-restful api

In a truly restful application I should follow links to reach my resources, while the only "magical already known URL" should be the application entry point. Direct queries like GET /user/john should be issued after having at least a link to /user or as a result from a search url specified by a previous link, like GET /user?username=john

But as following links forces more features, further development time and a smarter client, the actual reality is that most of the restful apis that I have written and used are partially restful: they are a collection of well defined URIs and methods, all previously known to the user by some documentation. In the end, the State Transfer part of what REST means is not present in most of them.

Well, following that reality where URLs are previously known, the 404 code turns to be an issue: How to differentiate the 2 meanings that 404 can have:

It is kinda important to differentiate those two scenarios because as a service maintainer, they are basically telling me if its an expect error and I should not be worried (first case) or an unexpected error and I should be worried as the service integration with my clients has issues (second case)

I tried searching for a better status code to represent the second case, and the closest ones I found were the 406 Not Acceptable (but it is a response directed to an Accept header that cannot be fulfilled) and the 410 Gone (that can be confusing as no resource was there, but the good part is that it tells the client to never try that URL again). Nevertheless, none of the two are good enough to be used for solving this

How did you or would you do to solve that?

Side node: python eve is an interesting project that tries to be a restful api with the State Transfer part. It implements HATEOAS for that

Upvotes: 2

Views: 4747

Answers (2)

xwoker
xwoker

Reputation: 3171

What about using 403 for the first case (together with the explanation) and 404 for the second? Since the RFC 403 refers to 404 as an alternative response code they might be related...

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.

403: You understand what the client wants but refuse to fulfill it. The client should not try again - it's forbidden until this resource is created - which you can explain as part of the answer.

404: You know that the client wants something you won't provide and can tell him in good faith, that this resource will never exists.

Update:

RFC 2119 explains how the "SHOULD NOT" has to be interpreted:

SHOULD NOT This phrase, or the phrase "NOT RECOMMENDED" mean that there may exist valid reasons in particular circumstances when the particular behavior is acceptable or even useful, but the full implications should be understood and the case carefully weighed before implementing any behavior described with this label.

I think for your use case this is true. The client request shouldn't be repeated *without solving the reason stated in the 403 answer: "accessing this resource is forbidden because no user named mario exists". But if the client is sure that the reason went away, he is free to try again. But this might be only my interpretation of the 403 "should not be repeated" statement.

Upvotes: 2

Remy Lebeau
Remy Lebeau

Reputation: 595762

There is no way to differentiate the two reasons, by design of RFC 2616 Section 10.4.5:

10.4.5 404 Not Found

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.

Upvotes: 1

Related Questions