Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In REST / Java, what should I return if my object is null?

I have a simple POJO that I annotated with REST annotations as follows:

@GET
@Path("/domains/{domainid}")
@Override
public Domain getDomain(@PathParam("domainid") UUID domainID) throws Exception {
    logger.info("Retrieving domain "+ domainID);
    Domain d = null;
    try {
        d = MyClient.getDomains().get(domainID.toString());
        logger.debug("Returning "+d.getName());
    } catch (Exception e) {
        logger.error("Could not retrieve domain", e);
    }
    return d;
}

Note that the log statement including d.getName() can actually throw an NPE which is then caught and logged. That's not pretty but it's also not the point here.

Ultimately whether d has a value or not, I return it.

In the case of a null value, my client receives an HTTP 204 status code. This is what wget displays: HTTP request sent, awaiting response... 204 No Content

Oddly enough, my browsers don't budge an inch. They still display the previous page (I suppose it makes sense to stay put when no content is received). I would have expected a blank page.

Three questions:

  • is HTTP 204 the right response to be returned?
  • how can I control that via annotations? Via other configuration?
  • what is the standard REST best practice regarding null objects?

Thanks

EDIT

There is a great question on the very same topic here: Is it correct to return 404 when a REST resource is not found?

like image 253
David Brossard Avatar asked Nov 11 '14 10:11

David Brossard


People also ask

How do you return a null object in Java?

You could change the method return type to return java. lang. Integer and then you can return null, and existing code that returns int will get autoboxed. Nulls are assigned only to reference types, it means the reference doesn't point to anything.

What happens when you return null in Java?

In Java, a null value can be assigned to an object reference of any type to indicate that it points to nothing. The compiler assigns null to any uninitialized static and instance members of reference type. In the absence of a constructor, the getArticles() and getName() methods will return a null reference.

What happens if you return null?

null is used to mean "not found / no value". If you mean something else, then return something else!

How do you handle null in Java?

null is a keyword in Java, "null" is just a string of text. 2. . equals() checks to see if two objects are equal according to the given method's definition of equality. Null checks should always be made using the == comparison operator, as it checks reference equality.


1 Answers

If the request is trying to GET/locate/find a resource, and it can't be found, traditionally, we should send a 404 Not Found. For further discussion see here.

That being said, I generally like to have my resource methods return Response, as it's easier to fine tune the response the way I want (a little - not much - more detail here). But seeing as how your method is overriding an interface contract (and returning a model object), JAX-RS gives us a nice hierarchy of exceptions that will get mapped to a particular response/status. The list can be seen here.

So in your particular case, if the resource can't be found, you can throw a WebApplicationException(Response.Status.NOT_FOUND) or a NotFoundException, and the exception will be mapped to a 404 Not Found. Something like

d = MyClient.getDomains().get(domainID.toString());
if (d == null) {
    throw new NotFoundException();  // <-- JAX-RS 2.0
    // or throw new WebApplicationException(Response.Status.NOT_FOUND);
                                    // ^^  JAX-RS 1.x 
}

The method will exit when the exception is thrown, and the client will receive a response with a 404 Not Found status.


Related Q&As

  • How to catch 404 (NotFoundException) without being dependant on a JAX-RS implementation?
  • Is it correct to return 404 when a REST resource is not found?

EDIT

In the first line I stated "If the request is trying to GET/locate/find a resource..", but really, this applies to almost all cases we are using URI templates, whether it is for a GET, POST, PUT, DELETE, whatever. Consider this example

@PUT
@Path("/customers/{id}")
public Response updateCustomer(@PathParam("id") long id, Customer customer) {
    ...
}

Here is a method that allows the client to update a customer via a PUT. The client should know the complete URI to the resource before trying to update it. If the {id} parameter (used for lookup) is not found say in a database, then the resource doesn't exist, and a 404 Not Found should also be returned to the client.

like image 152
Paul Samsotha Avatar answered Sep 18 '22 22:09

Paul Samsotha