HTTP Response Codes – Should a 204 or 404 Be Returned When a Resource is Not Found?

httpjavarestweb services

I am developing a simple RESTful service for tournaments and schedules. When a tournament is created through a POST request containing a JSON body, the tournament is inserted in a BiMap, declared as follows in a DAO implementation:

private BiMap<String, Tournament> tournaments = Maps.synchronizedBiMap(HashBiMap.create());

When a tournament is created, its associated string id is returned so the user can have future reference of that tournament. He/she can get information back from the new tournament performing the following request:

GET http://localhost:8080/eventscheduler/c15268ce-474a-49bd-a623-b0b865386f39

But what if no tournament with such id is found? So far, I am returning a 204 response. Well, Jersey is doing it for me when returning null from one of its methods. This is the method that corresponds to the route above:

@Path("/{id}")
@GET
@Produces(MediaType.APPLICATION_JSON)
public Tournament getTournament(@PathParam("id") String id) {
    Optional<Tournament> optTournament = tournamentDao.getTournament(id);
    if (optTournament.isPresent())
        return optTournament.get();
    return null;
}

My question is: is it OK to return a 204: No Content response, or should it be a 404 response instead, since the resource was not found?

If I should change it to a 404, obvious question: I should change the method signature right? Since now a tournament (of type Tournament) might not be returned, the method should look different. Should I use the Response type as the return type instead?

Best Answer

HTTP 204 means that something was found, but it's empty. For instance, imagine that you're serving log files through HTTP, with the requests such as http://example.com/logs/[date-goes-here]. On May 18th, 2015:

  • http://example.com/logs/2015-05-19 would return HTTP 404, which means that there are no logs, because, well, it's difficult to log the future.

  • http://example.com/logs/2015-05-18, however, would return either HTTP 200 with the log entries in the content of the response, or HTTP 204 if the log file was created, but there are still no logs recorded yet for this date.

If you provide null to the framework as a response to a request, it assumes that you found an entry, and this entry is empty, thus HTTP 204. Instead, you should throw new NotFoundException(); to indicate to the framework that the entry doesn't exist, so that it would generate a HTTP 404.

If I should change it to a 404, obvious question: I should change the method signature right?

No, you don't. That's the nice thing about throw new NotFoundException();. It will work no matter what is the actual return type of your method.