Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use of HTTP 204 vs 200 vs 404 to safely signal that a resource doesn't exist

In my REST API I have the normal CRUD endpoints for some resources. If I do a GET /items/42 and there is no such item, the normal behaviour would be to return a 404 NOT FOUND.

However, one scenario concerns me. In this scenario, a client needs to check if a resource (which is implicitly idenfitied by a token) exists, and if not, create it. So, the client would try to retrieve the resource, and if a 404 is received the client application would display the UI necessary for creating the item, and then proceed to POSTing the new resource. In a way, this is a special kind of resource, because since its ID is derived from other parameters, it's known even before creation. As an example, consider a user sign-up procedure; the client would ask "Do I exist? If no -> register me".

My concern is really whether I ever need to worry about "spurious" 404:s? Considering a server is usually surrounded by API gateways, reverse proxies and such, is there any risk that a 404 NOT FOUND could be produced by a surrounding entity due to some temporary error not related to the REST server itself? If so, it could trick the client into believing that the item is not created yet, and that it should now be created. Even if the resulting POST request to create the item would fail because the item already exists, this isn't very nice because the user may have entered data etc for no reason.

Is this a problem to take into account or just overly paranoid? I guess if clients can't trust a 404 to be idempotent (until the resource is created, of course), many other issues arise. Is there any actual situation where an API gateway or similar would report a 404 on its own?

If this is a valid scenario, do I need a "safer", more explicit response saying that the request definetely succeeded but the resource wasn't found, such as responding with a 200 OK with an empty JSON body or a {isRegistered: false}, a 204 NO CONTENT, or similar? This opens up for other strange things - if a request for a resource that doesn't exist would respond with a 200 accompanied by an empty body, perhaps creation of the item would be a PUT rather than a POST, etc? This seems like a can of worms... It all boils down to "Does a 404 guarantee that the given resource doesn't exist?".

like image 322
JHH Avatar asked Oct 18 '22 16:10

JHH


1 Answers

404 is pretty unambiguous : the resource wasn't found and it's a client error (4xx). Normally, server-side errors (5xx) can't interfere and create spurious 404's here.

As an alternative, if the resource to be created is linked to another resource in a unique way, you could use OPTIONS to ask the server if it already exists.

For instance :

OPTIONS /visitors/7883930/user-account

=> Allow: POST,OPTIONS (doesn't exist)

=> Allow: GET,OPTIONS (exists)

The key here is to have a URI that allows accessing the resource without knowing its ID. It is not always possible though.

like image 114
guillaume31 Avatar answered Oct 21 '22 09:10

guillaume31