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:
@GET
returns an Entity@POST
returns an HTTP response with the actual entity created@PUT
returns an HTTP response with the actual entity updated@DELETE
returns an HTTP response with the actual entity deletedHere 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);
}
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
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.
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.
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
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
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.