Bygge mikrotjenester med Eclipse MicroProfile

1. Oversikt

I denne artikkelen vil vi fokusere på å bygge en mikroservice basert på Eclipse MicroProfile.

Vi ser på hvordan du skriver en RESTful webapplikasjon ved hjelp av JAX-RS, CDI og JSON-P APIer.

2. En mikroservicearkitektur

Enkelt sagt, mikrotjenester er en programvarearkitekturstil som danner et komplett system som en samling av flere uavhengige tjenester.

Hver og en fokuserer på en funksjonell omkrets og kommuniserer til de andre med en språkagnostisk protokoll, for eksempel REST.

3. Formørkelse MicroProfile

Eclipse MicroProfile er et initiativ som tar sikte på å optimalisere Enterprise Java for Microservices-arkitekturen. Den er basert på en delmengde av Jakarta EE WebProfile APIer, slik at vi kan bygge MicroProfile-applikasjoner som vi bygger Jakarta EE-programmer.

Målet med MicroProfile er å definere standard APIer for å bygge mikrotjenester og levere bærbare applikasjoner på tvers av flere MicroProfile-driftstider.

4. Maven Avhengigheter

Alle avhengigheter som kreves for å bygge en Eclipse MicroProfile-applikasjon, leveres av denne avhengighetslisten (Bill of Materials):

 org.eclipse.microprofile mikroprofile 1.2 pom levert 

Omfanget er satt som sørget for fordi MicroProfile-kjøretiden allerede inkluderer API og implementering.

5. Representasjonsmodell

La oss starte med å lage en rask ressursklasse:

public class Book {private String id; privat strengnavn; privat strengforfatter; private heltalssider; // ...}

Som vi kan se, er det ingen merknader om dette Bok klasse.

6. Bruke CDI

Enkelt sagt, CDI er et API som gir avhengighetsinjeksjon og livssyklusadministrasjon. Det forenkler bruken av Enterprise bønner i webapplikasjoner.

La oss nå lage en CDI-administrert bønne som en butikk for bokrepresentasjonen:

@ApplicationScoped offentlig klasse BookManager {private ConcurrentMap inMemoryStore = ny ConcurrentHashMap (); public String add (Book book) {// ...} public Book get (String id) {// ...} public List getAll () {// ...}} 

Vi kommenterer denne klassen med @ApplicationScoped fordi vi bare trenger en forekomst hvis tilstand deles av alle klienter. Til det brukte vi en ConcurrentMap som en typesikker minnebutikk. Så la vi til metoder for CRUD operasjoner.

Nå er bønnen vår CDI klar og kan injiseres i bønnen BookEndpoint bruker de @Injiser kommentar.

7. JAX-RS API

For å lage en REST-applikasjon med JAX-RS, må vi lage en applikasjon klasse kommentert med @ApplicationPath og en ressurs kommentert med @Sti.

7.1. JAX RS-applikasjon

JAX-RS-applikasjonen identifiserer den grunnleggende URI-en under hvilken vi eksponerer ressursen i en webapplikasjon.

La oss lage følgende JAX-RS-applikasjon:

@ApplicationPath ("/ library") offentlig klasse LibraryApplication utvider applikasjonen {}

I dette eksemplet er alle JAX-RS-ressursklasser i webapplikasjonen tilknyttet LibraryApplication gjør dem under det samme bibliotek sti, det er verdien av ApplicationPath-merknad.

Denne merkede klassen forteller JAX RS kjøretid at den skal finne ressurser automatisk og avsløre dem.

7.2. JAX RS endepunkt

An Endepunkt klasse, også kalt Ressurs klasse, skal definere en ressurs selv om mange av de samme typene er teknisk mulig.

Hver Java-klasse kommentert med @Sti, eller har minst en metode kommentert med @Path eller @HttpMethod er et sluttpunkt.

Nå oppretter vi et JAX-RS-endepunkt som avslører representasjonen:

@Path ("books") @RequestScoped public class BookEndpoint {@Inject private BookManager bookManager; @GET @Path ("{id}") @Produces (MediaType.APPLICATION_JSON) public Response getBook (@PathParam ("id") Streng-id) {return Response.ok (bookManager.get (id)). Build (); } @GET @Produces (MediaType.APPLICATION_JSON) public Response getAllBooks () {return Response.ok (bookManager.getAll ()). Build (); } @POST @Consumes (MediaType.APPLICATION_JSON) public Response add (Book book) {String bookId = bookManager.add (book); returnere Response.created (UriBuilder.fromResource (this.getClass ()) .path (bookId) .build ()) .build (); }} 

På dette punktet kan vi få tilgang til BookEndpoint Ressurs under / bibliotek / bøker sti i webapplikasjonen.

7.3. JAX RS JSON Medietype

JAX RS støtter mange medietyper for kommunikasjon med REST-klienter, men Eclipse MicroProfile begrenser bruken av JSON som det spesifiserer bruken av JSOP-P API. Som sådan må vi kommentere metodene våre med @Consumes (MediaType.APPLICATION_JSON) og @Produserer (MediaType.APPLICATION_JSON).

De @Forbruker merknader begrenser de aksepterte formatene - i dette eksemplet godtas bare JSON-dataformat. HTTP-forespørselstittel Innholdstype bør være søknad / json.

Den samme ideen ligger bak @Produkter kommentar. JAX RS Runtime skal gjøre svaret på JSON-format. Forespørselen HTTP-overskrift Aksepterer bør være søknad / json.

8. JSON-P

JAX RS Runtime støtter JSON-P ut av esken slik at vi kan bruke JsonObject som metodeinngangsparameter eller returtype.

Men i den virkelige verden jobber vi ofte med POJO-klasser. Så vi trenger en måte å kartlegge mellom JsonObject og POJO. Her spiller JAX RS-enhetsleverandøren.

For marshaling av JSON-inngangsstrøm til Bok POJO, det påkaller en ressursmetode med en parameterparameter Bok, vi trenger å lage en klasse BookMessageBodyReader:

@Provider @Consumes (MediaType.APPLICATION_JSON) public class BookMessageBodyReader implementerer MessageBodyReader {@Override public boolean isReadable (Class type, Type genericType, Annotation [] annotations, MediaType mediaType) {return type.equals (Book.class); } @Override public Book readFrom (Class type, Type genericType, Annotation [] annotations, MediaType mediaType, MultivaluedMap httpHeaders, InputStream entityStream) kaster IOException, WebApplicationException {return BookMapper.map (entityStream); }} 

Vi gjør den samme prosessen for å unmarshal a Bok til JSON-utgangsstrøm, som påkaller en ressursmetode hvis returtype er Bok, ved å lage en BookMessageBodyWriter:

@Provider @Produces (MediaType.APPLICATION_JSON) offentlig klasse BookMessageBodyWriter implementerer MessageBodyWriter {@Override public boolean isWriteable (Class type, Type genericType, Annotation [] annotations, MediaType mediaType) {return type.equals (Book.class); } // ... @Override public void writeTo (Book book, Class type, Type genericType, Annotation [] annotations, MediaType mediaType, MultivaluedMap httpHeaders, OutputStream entityStream) kaster IOException, WebApplicationException {JsonWriter jsonWriter = Json.createWriter (entity) JsonObject jsonObject = BookMapper.map (bok); jsonWriter.writeObject (jsonObject); jsonWriter.close (); }} 

Som BookMessageBodyReader og BookMessageBodyWriter er merket med @Forsørger, blir de automatisk registrert av JAX RS kjøretid.

9. Bygging og drift av applikasjonen

Et MicroProfile-program er bærbart og skal kjøres i en hvilken som helst kompatibel MicroProfile-kjøretid. Vi forklarer hvordan vi bygger og kjører applikasjonen vår i Open Liberty, men vi kan bruke hvilken som helst kompatibel Eclipse MicroProfile.

Vi konfigurerer Open Liberty kjøretid gjennom en konfigurasjonsfil server.xml:

  jaxrs-2.0 cdi-1.2 jsonp-1.0 

La oss legge til pluginet liberty-maven-plugin til vår pom.xml:

  net.wasdev.wlp.maven.plugins liberty-maven-plugin 2.1.2 io.openliberty openliberty-runtime 17.0.0.4 zip $ {basedir} /src/main/liberty/config/server.xml $ {package.file} $ {packaging.type} falskt prosjekt / $ {project.artifactId} - $ {project.version} .war 9080 9443 installasjonsserver forberedelsespakke installasjonsserver opprett server installasjonsfunksjon pakke-server-med-apps pakkeinstallasjon- apps pakke-server 

Denne plugin-en kan konfigureres med et sett med egenskaper:

  biblioteket $ {project.build.directory} / $ {app.name} -service.jar kan kjøres 

Exec-målet ovenfor produserer en kjørbar jar-fil slik at applikasjonen vår blir en uavhengig mikroservice som kan distribueres og kjøres isolert. Vi kan også distribuere det som Docker-bilde.

For å lage en kjørbar jar, kjør følgende kommando:

mvn-pakke 

Og for å kjøre mikroservicen bruker vi denne kommandoen:

java -jar target / library-service.jar

Dette vil starte Open Liberty kjøretid og distribuere tjenesten vår. Vi kan få tilgang til sluttpunktet vårt og få alle bøkene på denne URL:

krøll // localhost: 9080 / bibliotek / bøker

Resultatet er en JSON:

[{"id": "0001-201802", "isbn": "1", "name": "Bygge mikroservice med Eclipse MicroProfile", "author": "baeldung", "pages": 420}] 

For å få en enkelt bok ber vi om denne nettadressen:

krøll // localhost: 9080 / bibliotek / bøker / 0001-201802

Og resultatet er JSON:

{"id": "0001-201802", "isbn": "1", "name": "Bygge mikroservice med Eclipse MicroProfile", "author": "baeldung", "pages": 420}

Nå legger vi til en ny bok ved å samhandle med API: et:

curl -H "Content-Type: application / json" -X POST -d '{"isbn": "22", "name": "Gradle in Action", "author": "baeldung", "pages": 420 } '// localhost: 9080 / bibliotek / bøker 

Som vi kan se, er statusen for svaret 201, noe som indikerer at boken ble opprettet, og plassering er URI som vi får tilgang til den:

<HTTP / 1.1 201 Opprettet <Sted: // localhost: 9080 / bibliotek / bøker / 0009-201802

10. Konklusjon

Denne artikkelen demonstrerte hvordan man bygger en enkel mikrotjeneste basert på Eclipse MicroProfile, som diskuterer JAX RS, JSON-P og CDI.

Koden er tilgjengelig på Github; dette er et Maven-basert prosjekt, så det skal være enkelt å importere og kjøre som det er.