JAX-RS è solo un'API!

1. Panoramica

Il paradigma REST esiste da diversi anni ormai e sta ancora ricevendo molta attenzione.

Un'API RESTful può essere implementata in Java in diversi modi: puoi usare Spring, JAX-RS o potresti semplicemente scrivere i tuoi servlet nudi se sei abbastanza bravo e coraggioso. Tutto ciò di cui hai bisogno è la capacità di esporre i metodi HTTP: il resto dipende da come li organizzi e da come guidi il client quando effettui chiamate alla tua API.

Come puoi capire dal titolo, questo articolo tratterà JAX-RS. Ma cosa significa "solo un'API"? Significa che l'attenzione qui è sul chiarire la confusione tra JAX-RS e le sue implementazioni e sull'offrire un esempio di come appare una webapp JAX-RS adeguata.

2. Inclusione in Java EE

JAX-RS non è altro che una specifica, un insieme di interfacce e annotazioni offerte da Java EE. E poi, ovviamente, abbiamo le implementazioni; alcuni dei più noti sono RESTEasy e Jersey.

Inoltre, se decidi di creare un server delle applicazioni conforme a JEE, i ragazzi di Oracle ti diranno che, tra molte altre cose, il tuo server dovrebbe fornire un'implementazione JAX-RS da utilizzare per le app distribuite. Ecco perché si chiama Java Enterprise Edition Platform .

Un altro buon esempio di specifica e implementazione è JPA e Hibernate.

2.1. Guerre leggere

In che modo tutto questo aiuta noi sviluppatori? L'aiuto sta nel fatto che i nostri distribuibili possono e devono essere molto sottili, consentendo al server delle applicazioni di fornire le librerie necessarie. Ciò si applica anche allo sviluppo di un'API RESTful: l'artefatto finale non deve contenere alcuna informazione sull'implementazione JAX-RS utilizzata.

Certo, possiamo fornire l'implementazione (ecco un tutorial per RESTeasy). Ma allora non possiamo più chiamare la nostra applicazione "app Java EE". Se domani arriva qualcuno e dice " Ok, è ora di passare a Glassfish o Payara, JBoss è diventato troppo costoso! “, Potremmo essere in grado di farlo, ma non sarà un lavoro facile.

Se forniamo la nostra implementazione, dobbiamo assicurarci che il server sappia escludere la propria - questo di solito accade avendo un file XML proprietario all'interno del deployable. Inutile dire che un file del genere dovrebbe contenere tutti i tipi di tag e istruzioni di cui nessuno sa nulla, tranne gli sviluppatori che hanno lasciato l'azienda tre anni fa.

2.2. Conosci sempre il tuo server

Finora abbiamo detto che dovremmo sfruttare la piattaforma che ci viene offerta.

Prima di decidere su un server da utilizzare, dovremmo vedere quale implementazione JAX-RS (nome, fornitore, versione e bug noti) fornisce, almeno per gli ambienti di produzione. Ad esempio, Glassfish viene fornito con Jersey, mentre Wildfly o Jboss vengono forniti con RESTEasy.

Questo, ovviamente, significa un po 'di tempo dedicato alla ricerca, ma dovrebbe essere fatto solo una volta, all'inizio del progetto o durante la migrazione su un altro server.

3. Un esempio

Se vuoi iniziare a giocare con JAX-RS, il percorso più breve è: avere un progetto webapp Maven con la seguente dipendenza nel pom.xml :

 javax javaee-api 7.0 provided  

Stiamo usando JavaEE 7 poiché ci sono già molti server di applicazioni che lo implementano. Quel jar API contiene le annotazioni che devi utilizzare, che si trovano nel pacchetto javax.ws.rs . Perché lo scopo è "fornito"? Perché anche questo jar non deve essere nella build finale: ne abbiamo bisogno in fase di compilazione ed è fornito dal server per il runtime.

Dopo che la dipendenza è stata aggiunta, dobbiamo prima scrivere la classe di ingresso: una classe vuota che estende javax.ws.rs.core.Application ed è annotata con javax.ws.rs.ApplicationPath:

@ApplicationPath("/api") public class RestApplication extends Application { } 

Abbiamo definito il percorso di ingresso come / api. Qualunque altro percorso dichiariamo per le nostre risorse, verrà preceduto da / api .

Quindi, vediamo una risorsa:

@Path("/notifications") public class NotificationsResource { @GET @Path("/ping") public Response ping() { return Response.ok().entity("Service online").build(); } @GET @Path("/get/{id}") @Produces(MediaType.APPLICATION_JSON) public Response getNotification(@PathParam("id") int id) { return Response.ok() .entity(new Notification(id, "john", "test notification")) .build(); } @POST @Path("/post/") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) public Response postNotification(Notification notification) { return Response.status(201).entity(notification).build(); } }

Abbiamo un semplice endpoint ping da chiamare e controllare se la nostra app è in esecuzione, un GET e un POST per una notifica (questo è solo un POJO con attributi più getter e setter).

Distribuisci questa guerra su qualsiasi server delle applicazioni che implementa JEE7 e i seguenti comandi funzioneranno:

curl //localhost:8080/simple-jaxrs-ex/api/notifications/ping/ curl //localhost:8080/simple-jaxrs-ex/api/notifications/get/1 curl -X POST -d '{"id":23,"text":"lorem ipsum","username":"johana"}' //localhost:8080/simple-jaxrs-ex/api/notifications/post/ --header "Content-Type:application/json"

Dove simple-jaxrs-ex è la root di contesto della webapp.

Questo è stato testato con Glassfish 4.1.0 e Wildfly 9.0.1.Final. Tieni presente che gli ultimi due comandi non funzioneranno con Glassfish 4.1.1, a causa di questo bug. Apparentemente è un problema noto in questa versione di Glassfish, per quanto riguarda la serializzazione di JSON (se devi usare questa versione del server, dovrai gestire il marshalling JSON da solo)

4. Conclusione

Alla fine di questo articolo, tieni presente che JAX-RS è un'API potente e la maggior parte (se non tutte) le cose di cui hai bisogno sono già implementate dal tuo server web. Non c'è bisogno di trasformare il tuo distribuibile in un mucchio ingestibile di librerie.

Questo articolo presenta un semplice esempio e le cose potrebbero diventare più complicate. Ad esempio, potresti scrivere i tuoi marshalers. Quando è necessario, cerca tutorial che risolvano il tuo problema con JAX-RS, non con Jersey, Resteasy o altre implementazioni concrete. È molto probabile che il tuo problema possa essere risolto con una o due annotazioni.