Search code examples
javaapirestjax-rsresteasy

What to return for different HTTP methods in JAX-RS?


I am practicing building RESTFUL API's using the RESTEasy implementation. But I am still a little bit confused about what should I return according to the HTTP method. This is the way that I am doing it for the moment:

  1. @GET returns an Entity
  2. @POST returns an HTTP response with the actual entity created
  3. @PUT returns an HTTP response with the actual entity updated
  4. @DELETE returns an HTTP response with the actual entity deleted

Here is an example of my controller for illustration.

@GET
@Path("/{bookId}")
@Produces(MediaType.APPLICATION_JSON_VALUE)
public Book getBookById(@PathParam("bookId") Integer bookId) {
    return bookService.getBookById(bookId);
}

@POST
@Consumes(MediaType.APPLICATION_JSON_VALUE)
@Produces(MediaType.APPLICATION_JSON_VALUE)
public Response inertBook(@Valid Book book) {
    return bookService.insertBook(book);
}

@DELETE
@Path("/{bookId}")
public Response deleteBook(@PathParam("bookId") Integer bookId) {
    return bookService.deleteBook(bookId);
}

@PUT
@Path("/{bookId}")
@Consumes(MediaType.APPLICATION_JSON_VALUE)
@Produces(MediaType.APPLICATION_JSON_VALUE)
public Response updateBook(@PathParam("bookId") Integer bookId, @Valid Book book) {
    return bookService.updateBook(bookId, book);
}

Solution

    1. GET - The client is trying to retrieve a resource or in other words, get a resource. So yes, you should return an entity with a status code of "200 OK" In most cases, it will either be a single resource or a collection resource; in your example, either a single book or all of the books

    2. POST - When you create a new resource, generally the client will send the representation of the new book to be created. What the client doesn't have is the identifier for the resource or how to access the resource later. What is generally done is a Location header is sent back to the client so the client can later access the resource. The status of this response should be "201 Created" Optionally, you can send back the same representation the client sent, but including the newly created identifier. You can see an example in this post.

    3. PUT - This is a complete update. So whatever the client sends completely overwrites the current resource (excluding the identifier). So ultimately, the client has all the information already; no need to send anything back. You can just respond back with a "204 No Content" status. In code terms, you can simply have a void method or return a Response to explicitly set the status.

    4. DELETE - If everything goes well with the delete, there is no need to send anything but to let the client know that everything is OK. So simply sending a "200 OK" response is suitable. Optionally, including the deleted representation may be OK.

    These are very general guidelines. Everyone has their own style, but most try to follow standards. Below are some resources you can dig into to learn more

    Aside

    I was looking at how your service layer implementation (your BookService class) and there are some design flaws. Generally, in a tiered application, the lower tiers should not know anything about the tier above it. Here is an example of tiers

      WEB
       ↓
    SERVICE
       ↓
      DAO
    
    • The WEB layer is the REST layer (the JAX-RS code)
    • The SERVICE layer is the BookService where the business happens
    • The DAO layer is data later where data access happens

    In this architecture, the DAO layer should not know about the SERVICE layer and SERVICE layer should not know about the WEB layer. In your example though, your service knows about Response objects. The Response should be only used in the WEB layer. A better implementation might look something like

    public Response getBook(@PathParam("id") long id) {
        Book book = bookService.findBook(id);
        if (book == null) {
            throw new NotFoundException();
        }
        return book;
    }
      
    

    Now the BookService only has the responsibility of finding the book and the resource method handles all of the web logic.