I servizi del progetto Library
Ora che abbiamo acquisito le competenze di base per lavorare con Jersey possiamo concentrarci sull'implementazione dei servizi della nostra libreria.
Innanzitutto aggiungiamo le classi Book
e Author
descritte nel capitolo precedente, quindi implementiamo le classi di servizi per manipolare tali oggetti. Ricordiamoci di collocare le classi di servizi nel package it.html.tutorial.library.api
.
La classe BookServices
esporrà i metodi CRUD per la gestione dell'oggetto Book
. Nel codice di seguito lavoriamo con degli stub, a seconda dei casi dovrà essere integrato il codice per la persistenza dei dati. L'annotation @Path
definisce l'URI dove saranno esposti i servizi, sempre relativo al path definito in fase di configurazione.
@Path("books")
public class BookServices {
@GET
public List list() {
List books = new ArrayList();
Author author = new Author();
author.setId(1);
author.setName("Joanne");
author.setSurname("Rowling");
Book book1 = new Book();
book1.setId(1);
book1.setTitle("Harry Potter and the Philosopher's Stone");
book1.setLanguage("english");
List authors = new ArrayList();
authors.add(author);
book1.setAuthors(authors);
books.add(book1);
Book book2 = new Book();
book2.setId(2);
book2.setTitle("Harry Potter and the Chamber of Secrets");
book2.setLanguage("english");
book2.setAuthors(authors);
books.add(book2);
return books;
}
@GET
@Path("{id}")
public Book get(@PathParam("{id}") long id) {
Author author = new Author();
author.setId(1);
author.setName("Joanne");
author.setSurname("Rowling");
Book book = new Book();
book.setId(1);
book.setTitle("Harry Potter and the Philosopher's Stone");
book.setLanguage("english");
List authors = new ArrayList();
authors.add(author);
book.setAuthors(authors);
return book;
}
@POST
public Response add(Book book) throws URISyntaxException {
long newId = 3;
return Response.created(new URI("api/books/" + newId)).build();
}
@PUT
@Path("{id}")
public Response update(@PathParam("{id}") long id, Book book) {
return Response.noContent().build();
}
@DELETE
@Path("{id}")
public Response delete(@PathParam("{id}") long id) {
return Response.noContent().build();
}
}
Come possiamo notare, abbiamo rispettato il paradigma HTTP sia in termini di corrispondenza fra metodi HTTP ed operazioni che in termini di codice di riposta restituito dal servizio. I metodi accettano comodamente come parametro di input oggetti Java Bean e restituiscono gli stessi. I parametri sulla URL possono essere letti tramite l'annotation @PathParam
e sono specificati sul path, utilizzando le parentesi graffe.
La classe AuthorServices
implementa invece i servizi relativi agli autori di un libro, e sono disponibili sulla URI relativa ad un libro identificato tramite un id.
@Path("books/{book_id}/authors")
public class AuthorServices {
@GET
public List list(@PathParam("{book_id}") long bookId) {
Author author = new Author();
author.setId(1);
author.setName("Joanne");
author.setSurname("Rowling");
List authors = new ArrayList();
authors.add(author);
return authors;
}
}
Testing
Una volta implementate le nostre classi nel progetto vediamo come effettuare dei semplici casi di test per assicurarci che tutto funzioni a dovere.
Proviamo il metodo per ottenere la lista dei libri, quindi da terminale:
curl -i http://localhost:8080/api/books
otterremo in riposta il JSON con la lista dei libri.
Per aggiungere un libro dovremmo invece passare a curl il JSON con i dati del libro.
curl -i -H "Content-type: application/json" http://localhost:8080/api/books \
-d '{"title": "Il mio libro", "language": "italiano"}'
In questo modo, all'interno del metodo add
nella classe BookServices
avremo l'oggetto Book
valorizzato con quanto passato sotto forma di JSON nel payload della richiesta. Inoltre, fra gli header della risposta notiamo Location
che servirà ad un client per conoscere l'URI e quindi l'id dell'oggetto appena creato.
Per modificare un libro, accediamo alla URI che identifica il libro specificandone l'id, e passiamo nel payload della richiesta i dati del libro per la modifica.
curl -i -H "Content-type: application/json" \
-X PUT http://localhost:8080/api/books/3 \
-d '{"title": "Il mio libro modificato", "language": "italiano"}'
In questo modo, all'interno del metodo update
nella classe BookServices
avremo valorizzati sia l'oggetto Book
con quanto passato sotto forma di JSON nel payload della richiesta, sia il parametro id
con l'identificativo del libro che intendiamo modificare. Questa volta il codice di risposta sarà un 204 in quanto in libro non è stato aggiunto bensì modificato.
Per cancellare un libro, accediamo sempre alla URI che identifica il libro specificandone l'id, questa volta senza dover passare nulla nel payload della richiesta.
curl -i -H "Content-type: application/json" \
-X DELETE http://localhost:8080/api/books/3
In questo modo, all'interno del metodo delete
nella classe BookServices
avremo valorizzato il parametro id
con l'identificativo del libro che vogliamo cancellare.