Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it correct to return 404 when a REST resource is not found?

Let's say I have a simple (Jersey) REST resource as follows:

@Path("/foos") public class MyRestlet         extends BaseRestlet {      @GET     @Path("/{fooId}")     @Produces(MediaType.APPLICATION_XML)     public Response getFoo(@PathParam("fooId") final String fooId)             throws IOException, ParseException     {         final Foo foo = fooService.getFoo(fooId);          if (foo != null)         {             return Response.status(Response.Status.OK).entity(foo).build();         }         else         {             return Response.status(Response.Status.NOT_FOUND).build();         }     }  } 

Based on the code above, is it correct to return a NOT_FOUND status (404), or should I be returning 204, or some other more appropriate code?

like image 718
carlspring Avatar asked Nov 10 '14 14:11

carlspring


People also ask

When should you return 404 Not Found?

If the server does not know, or has no facility to determine, whether or not the condition is permanent, the status code 404 (Not Found) SHOULD be used instead.

Should a non existent page always return 404?

404s should not always be redirected. 404s should not be redirected globally to the home page. 404s should only be redirected to a category or parent page if that's the most relevant user experience available. It's okay to serve a 404 when the page doesn't exist anymore (crazy, I know).

How do I fix REST API 404?

You fix this by opening the listen step in your VSM file, and changing the base path in there, so you don't get a 404 error. You could change that to "/api/" so any api requests are dealt-with, or "/api/retrieveId/" so only retrieveId messages are dealt-with, or "/" so all requests are dealt-with.

What can someone say if your API returns 404?

404 means The server has not found anything matching the Request-URI. If you put in the wrong URI or bad URI that is your problem and the reason you didn't get to a resource whether a HTML page or IMG.


2 Answers

Yes, it is pretty common to return 404 for a resource not being found. Just like a web page, when it's not found, you get a 404. It's not just REST, but an HTTP standard.

Every resource should have a URL location. URLs don't need to be static, they can be templated. So it's possible for the actual requested URL to not have a resource. It is the server's duty to break down the URL from the template to look for the resource. If they resource doesn't exist, then it's "Not Found"

Here's from the HTTP 1.1 spec

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.


Here's for 204

204 No Content

The server has fulfilled the request but does not need to return an entity-body, and might want to return updated metainformation. The response MAY include new or updated metainformation in the form of entity-headers, which if present SHOULD be associated with the requested variant.

If the client is a user agent, it SHOULD NOT change its document view from that which caused the request to be sent. This response is primarily intended to allow input for actions to take place without causing a change to the user agent's active document view, although any new or updated metainformation SHOULD be applied to the document currently in the user agent's active view.

The 204 response MUST NOT include a message-body, and thus is always terminated by the first empty line after the header fields.

Normally 204 would be used when a representation has been updated or created and there's no need to send an response body back. In the case of a POST, you could send back just the Location of the newly created resource. Something like

@POST @Path("/something") @Consumes(...) public Response createBuzz(Domain domain, @Context UriInfo uriInfo) {     int domainId = // create domain and get created id     UriBuilder builder = uriInfo.getAbsolutePathBuilder();     builder.path(Integer.toString(domainId));  // concatenate the id.     return Response.created(builder.build()).build(); } 

The created(URI) will send back the response with the newly created URI in the Location header.


Adding to the first part. You just need to keep in mind that every request from a client is a request to access a resource, whether it's just to GET it, or update with PUT. And a resource can be anything on the server. If the resource doesn't exist, then a general response would be to tell the client we can't find that resource.

To expand on your example. Let's say FooService accsses the DB. Each row in the database can be considered a resource. And each of those rows (resources) has a unique URL, like foo/db/1 might locate a row with a primary key 1. If the id can't be found, then that resource is "Not Found"

like image 37
Paul Samsotha Avatar answered Sep 24 '22 21:09

Paul Samsotha


A 404 response in this case is pretty typical and easy for API users to consume.

One problem is that it is difficult for a client to tell if they got a 404 due to the particular entity not being found, or due to a structural problem in the URI. In your example, /foos/5 might return 404 because the foo with id=5 does not exist. However, /food/1 would return 404 even if foo with id=1 exists (because foos is misspelled). In other words, 404 means either a badly constructed URI or a reference to a non-existent resource.

Another problem arises when you have a URI that references multiple resources. With a simple 404 response, the client has no idea which of the referenced resources was not found.

Both of these problems can be partially mitigated by returning additional information in the response body to let the caller know exactly what was not found.

like image 139
Rob Avatar answered Sep 23 '22 21:09

Rob