JAX-RS er bare en API!

1. Oversigt

REST-paradigmet har eksisteret i et par år nu, og det får stadig stor opmærksomhed.

En RESTful API kan implementeres i Java på en række måder: Du kan bruge Spring, JAX-RS, eller du kan bare skrive dine egne bare servlets, hvis du er god og modig nok. Alt hvad du behøver er evnen til at eksponere HTTP-metoder - resten handler om, hvordan du organiserer dem, og hvordan du guider klienten, når du foretager opkald til din API.

Som du kan se ud fra titlen, vil denne artikel dække JAX-RS. Men hvad betyder "bare en API"? Det betyder, at fokus her er på at afklare forvirringen mellem JAX-RS og dens implementeringer og på at tilbyde et eksempel på, hvordan en ordentlig JAX-RS-webapp ser ud.

2. Inkludering i Java EE

JAX-RS er intet andet end en specifikation, et sæt grænseflader og kommentarer, der tilbydes af Java EE. Og så har vi selvfølgelig implementeringerne; nogle af de mere kendte er RESTEasy og Jersey.

Også, hvis du nogensinde beslutter at opbygge en JEE-kompatibel applikationsserver, vil fyrene fra Oracle fortælle dig, at din server blandt mange andre ting skal give en JAX-RS-implementering, som de implementerede apps kan bruge. Derfor hedder det Java Enterprise Edition Platform.

Et andet godt eksempel på specifikation og implementering er JPA og Hibernate.

2.1. Letvægtskrige

Så hvordan hjælper alt dette os, udviklerne? Hjælpen er, at vores implementerbare kan og burde være meget tynde, så applikationsserveren leverer de nødvendige biblioteker. Dette gælder også når der udvikles en RESTful API: den endelige artefakt bør ikke indeholde nogen information om den anvendte JAX-RS-implementering.

Sikker på, vi kan levere implementeringen (her er en tutorial til RESTeasy). Men så kan vi ikke længere kalde vores applikation "Java EE-app". Hvis i morgen kommer nogen og siger “Ok, tid til at skifte til Glassfish eller Payara, JBoss blev for dyrt!”Vi kan muligvis gøre det, men det bliver ikke et let job.

Hvis vi leverer vores egen implementering, skal vi sørge for, at serveren ved at ekskludere sin egen - dette sker normalt ved at have en proprietær XML-fil inde i den implementerbare. Det er overflødigt at sige, at en sådan fil skal indeholde alle mulige tags og instruktioner, som ingen ved noget om, undtagen udviklerne, der forlod virksomheden for tre år siden.

2.2. Kend altid din server

Vi sagde hidtil, at vi skulle udnytte den platform, vi tilbydes.

Før vi beslutter at bruge en server, skal vi se, hvilken JAX-RS-implementering (navn, leverandør, version og kendte fejl) den giver, i det mindste til produktionsmiljøer. For eksempel kommer Glassfish med Jersey, mens Wildfly eller Jboss kommer med RESTEasy.

Dette betyder selvfølgelig lidt tid brugt på forskning, men det skal kun gøres en gang i starten af ​​projektet, eller når du migrerer det til en anden server.

3. Et eksempel

Hvis du vil begynde at spille med JAX-RS, er den korteste vej: have et Maven webapp-projekt med følgende afhængighed i pom.xml:

 javax javaee-api 7.0 leveret 

Vi bruger JavaEE 7, da der allerede er masser af applikationsservere, der implementerer den. Denne API-krukke indeholder de kommentarer, du skal bruge, placeret i pakken javax.ws.rs. Hvorfor er omfanget "tilvejebragt"? Da denne krukke heller ikke behøver at være i den endelige version - vi har brug for den på kompileringstidspunktet, og den leveres af serveren i løbetid.

Når afhængigheden er tilføjet, skal vi først skrive indgangsklassen: en tom klasse, der strækker sig javax.ws.rs.core.Applikation og er kommenteret med javax.ws.rs.ApplicationPath:

@ApplicationPath ("/ api") offentlig klasse RestApplication udvider applikationen {} 

Vi definerede indgangsstien som værende / api. Uanset hvilke andre veje vi erklærer for vores ressourcer, vil de blive forud for / api.

Lad os derefter se en ressource:

@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", "testnotifikation")) .build (); } @POST @Path ("/ post /") @Consumes (MediaType.APPLICATION_JSON) @Produces (MediaType.APPLICATION_JSON) public Response postNotification (Notification notification) {return Response.status (201) .entity (notification) .build () ; }}

Vi har et simpelt ping-slutpunkt til at ringe og kontrollere, om vores app kører, en GET og en POST for en underretning (dette er bare en POJO med attributter plus getters og settere).

Distribuer denne krig på enhver applikationsserver, der implementerer JEE7, og følgende kommandoer fungerer:

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 "

Hvor simple-jaxrs-ex er kontekst-rod til webapp.

Dette blev testet med Glassfish 4.1.0 og Wildfly 9.0.1.Final. Bemærk, at de sidste to kommandoer ikke fungerer med Glassfish 4.1.1 på grund af denne fejl. Det er tilsyneladende et kendt problem i denne Glassfish-version med hensyn til serialisering af JSON (hvis du skal bruge denne serverversion, skal du administrere JSON-marshaling alene)

4. Konklusion

I slutningen af ​​denne artikel skal du bare huske på, at JAX-RS er en kraftfuld API, og de fleste (hvis ikke alle) ting, du har brug for, er allerede implementeret af din webserver. Ingen grund til at gøre din implementering til en uhåndterbar bunke af biblioteker.

Denne opskrivning præsenterer et simpelt eksempel, og tingene kan blive mere komplicerede. For eksempel vil du måske skrive dine egne marskalk. Når det er nødvendigt, skal du kigge efter vejledninger, der løser dit problem med JAX-RS, ikke med Jersey, Resteasy eller anden konkret implementering. Det er meget sandsynligt, at dit problem kan løses med en eller to kommentarer.