En introduksjon til vår-HATEOAS

REST Topp

Jeg kunngjorde nettopp det nye Lær våren kurs, med fokus på det grunnleggende i vår 5 og vårstøvel 2:

>> KONTROLLER KURSET

1. Oversikt

Denne artikkelen forklarer prosessen med å lage hypermediadrevet REST-nettjeneste ved hjelp av Spring HATEOAS-prosjektet.

2. Vår-HATEOAS

Spring HATEOAS-prosjektet er et bibliotek med APIer som vi kan bruke til å lage REST-representasjoner som følger prinsippet til HATEOAS (Hypertext as the Engine of Application State).

Generelt sett innebærer prinsippet at APIen skal veilede klienten gjennom applikasjonen ved å returnere relevant informasjon om de neste potensielle trinnene, sammen med hvert svar.

I denne artikkelen skal vi bygge et eksempel ved bruk av Spring HATEOAS med mål om å koble fra klienten og serveren, og teoretisk la APIen endre URI-ordningen uten å bryte klienter.

3. Klargjøring

La oss først legge til våren HATEOAS avhengighet:

 org.springframework.boot spring-boot-starter-hateoas 2.1.4.RELEASE 

Hvis vi ikke bruker Spring Boot, kan vi legge til følgende biblioteker i prosjektet vårt:

 org.springframework.hateoas spring-hateoas 0.25.1.RELEASE org.springframework.plugin spring-plugin-core 1.2.0.RELEASE 

Som alltid kan vi søke i de nyeste versjonene av starteren HATEOAS, vår-hatoas og vår-plugin-kjerneavhengighet i Maven Central.

Deretter har vi Kunde ressurs uten Spring HATEOAS-støtte:

offentlig klasse kunde {private String customerId; private String kundenavn; private String companyName; // standard getters og setters} 

Og vi har en kontrollerklasse uten Spring HATEOAS-støtte:

@RestController @RequestMapping (verdi = "/ kunder") offentlig klasse CustomerController {@Autowired private CustomerService customerService; @GetMapping ("/ {customerId}") offentlig kunde getCustomerById (@PathVariable String customerId) {return customerService.getCustomerDetail (customerId); }} 

Til slutt, Kunde ressursrepresentasjon:

{"customerId": "10A", "customerName": "Jane", "customerCompany": "ABC Company"} 

4. Legge til HATEOAS-støtte

I et Spring HATEOAS-prosjekt trenger vi ikke å slå opp Servlet-konteksten eller sammenkoble sti-variabelen til basen URI.

I stedet, Spring HATEOAS tilbyr tre abstraksjoner for å lage URI - RepresentationModel, Link og WebMvcLinkBuilder. Vi kan bruke disse til å lage metadataene og knytte dem til ressursrepresentasjonen.

4.1. Legge til Hypermedia-støtte i en ressurs

Prosjektet gir en basisklasse kalt RepresentasjonModell å arve fra når du oppretter en ressursrepresentasjon:

offentlig klasse Kunde utvider RepresentationModel {private String customerId; private String kundenavn; private String companyName; // standard getters og setters} 

De Kunde ressurs strekker seg fra RepresentasjonModell klasse å arve legge til() metode. Så når vi oppretter en lenke, kan vi enkelt sette verdien til ressursrepresentasjonen uten å legge til noen nye felt i den.

4.2. Opprette lenker

Spring HATEOAS gir en Link objekt for å lagre metadataene (ressursens beliggenhet eller URI).

Først oppretter vi en enkel lenke manuelt:

Link link = new Link ("// localhost: 8080 / spring-security-rest / api / customers / 10A"); 

De Link gjenstand følger Atom koblingssyntaks og består av en rel som identifiserer relasjon til ressursen og href attributt som er selve koblingen.

Slik gjør du Kunde ressurs ser ut nå som den inneholder den nye lenken:

{"customerId": "10A", "customerName": "Jane", "customerCompany": "ABC Company", "_links": {"self": {"href": "// localhost: 8080 / spring-security -rest / api / kunder / 10A "}}} 

URI assosiert med responsen er kvalifisert som en selv- lenke. Semantikken til selv- forholdet er klart - det er ganske enkelt den kanoniske plasseringen ressursen kan nås på.

4.3. Lage bedre lenker

En annen veldig viktig abstraksjon som tilbys av biblioteket er de WebMvcLinkBuilder - som forenkler å bygge URI-er ved å unngå hardkodede lenker.

Følgende tekstutdrag viser hvordan du bygger kundens egenlink ved hjelp av WebMvcLinkBuilder klasse:

linkTo (CustomerController.class) .slash (customer.getCustomerId ()). withSelfRel (); 

La oss se:

  • de link til() metoden inspiserer kontrollerklassen og oppnår rotkartleggingen
  • de skråstrek() metoden legger til Kunde ID verdi som sti-variabel for lenken
  • endelig, den withSelfMethod () kvalifiserer forholdet som en selvlink

5. Forhold

I forrige avsnitt har vi vist en selvhenvisende relasjon. Imidlertid kan mer komplekse systemer også innebære andre relasjoner.

For eksempel, a kunde kan ha et forhold til ordrer. La oss modellere Rekkefølge klasse også som en ressurs:

public class Order utvider RepresentationModel {private String orderId; privat dobbel pris; privat int mengde; // standard getters og setters} 

På dette punktet kan vi utvide CustomerController med en metode som returnerer alle bestillinger fra en bestemt kunde:

@GetMapping (value = "/ {customerId} / orders", produserer = {"application / hal + json"}) offentlig CollectionModel getOrdersForCustomer (@PathVariable final String customerId) {List orders = orderService.getAllOrdersForCustomer (customerId); for (endelig bestillingsordre: ordrer) {Link selfLink = linkTo (methodOn (CustomerController.class) .getOrderById (customerId, order.getOrderId ())). withSelfRel (); order.add (selfLink); } Link link = linkTo (methodOn (CustomerController.class) .getOrdersForCustomer (customerId)). WithSelfRel (); CollectionModel resultat = nytt CollectionModel (bestillinger, lenke); returresultat; } 

Metoden vår returnerer a CollectionModel motsette seg å overholde HAL-returtypen, samt en “_selv" lenke for hver bestilling og hele listen.

En viktig ting å merke seg her er at hyperkoblingen for kundeordrene avhenger av kartleggingen av getOrdersForCustomer () metode. Vi vil referere til disse typer lenker som metodekoblinger og vise hvordan WebMvcLinkBuilder kan hjelpe til med deres opprettelse.

6. Koblinger til kontrollermetoder

De WebMvcLinkBuilder tilbyr rik støtte til Spring MVC Controllers. Følgende eksempel viser hvordan du bygger HATEOAS hyperkoblinger basert på getOrdersForCustomer () metoden for CustomerController klasse:

Link ordersLink = linkTo (methodOn (CustomerController.class) .getOrdersForCustomer (customerId)). WithRel ("allOrders"); 

De methodOn () oppnår metodekartleggingen ved å lage dummyanrop på målmetoden på proxy-kontrolleren og stiller inn Kunde ID som banevariabelen til URI.

7. Vår-HATEOAS i aksjon

La oss sette opprettelsen av selvlink og metodekobling sammen i en getAllCustomers () metode:

@GetMapping (produserer = {"application / hal + json"}) offentlig CollectionModel getAllCustomers () {Liste allCustomers = customerService.allCustomers (); for (Kundekunde: allCustomers) {String customerId = customer.getCustomerId (); Link selfLink = linkTo (CustomerController.class) .slash (customerId) .withSelfRel (); customer.add (selfLink); if (orderService.getAllOrdersForCustomer (customerId) .size ()> 0) {Link ordersLink = linkTo (methodOn (CustomerController.class) .getOrdersForCustomer (customerId)). withRel ("allOrders"); customer.add (ordersLink); }} Linklink = linkTo (CustomerController.class) .withSelfRel (); CollectionModel resultat = nytt CollectionModel (allCustomers, lenke); returresultat; }

La oss påkalle getAllCustomers () metode:

curl // localhost: 8080 / spring-security-rest / api / customers 

Og undersøk resultatet:

{"_embedded": {"customerList": [{"customerId": "10A", "customerName": "Jane", "companyName": "ABC Company", "_links": {"self": {"href" : "// localhost: 8080 / spring-security-rest / api / customers / 10A"}, "allOrders": {"href": "// localhost: 8080 / spring-security-rest / api / customers / 10A / ordrer "}}}, {" customerId ":" 20B "," customerName ":" Bob "," companyName ":" XYZ Company "," _links ": {" self ": {" href ":" // localhost : 8080 / spring-security-rest / api / customers / 20B "}," allOrders ": {" href ":" // localhost: 8080 / spring-security-rest / api / customers / 20B / orders "}}} , {"customerId": "30C", "customerName": "Tim", "companyName": "CKV Company", "_links": {"self": {"href": "// localhost: 8080 / spring- security-rest / api / customers / 30C "}}}]}," _links ": {" self ": {" href ":" // localhost: 8080 / spring-security-rest / api / customers "}}}

Innenfor hver ressursrepresentasjon er det en selv- lenke og alle bestillinger lenke for å trekke ut alle bestillinger fra en kunde. Hvis en kunde ikke har bestillinger, vises ikke koblingen for bestillinger.

Dette eksemplet viser hvordan Spring HATEOAS fremmer API-oppdagbarhet i en hviletjeneste. Hvis lenken eksisterer, kan klienten følge den og få alle bestillinger til en kunde:

curl // localhost: 8080 / spring-security-rest / api / customers / 10A / orders 
{"_embedded": {"orderList": [{"orderId": "001A", "price": 150, "amount": 25, "_links": {"self": {"href": "// localhost : 8080 / spring-security-rest / api / customers / 10A / 001A "}}}, {" orderId ":" 002A "," price ": 250," amount ": 15," _links ": {" self " : {"href": "// localhost: 8080 / spring-security-rest / api / customers / 10A / 002A"}}}]}, "_links": {"self": {"href": "// localhost: 8080 / spring-security-rest / api / customers / 10A / orders "}}}

8. Konklusjon

I denne opplæringen har vi diskutert hvordan du gjør det bygge en hypermediadrevet Spring REST-nettjeneste ved hjelp av Spring HATEOAS-prosjektet.

I eksemplet ser vi at klienten kan ha et enkelt inngangspunkt til applikasjonen, og ytterligere handlinger kan utføres basert på metadataene i responsrepresentasjonen.

Dette gjør at serveren kan endre URI-ordningen uten å bryte klienten. Programmet kan også annonsere for nye funksjoner ved å sette nye lenker eller URI-er i representasjonen.

Til slutt finner du full implementering av denne artikkelen i GitHub-prosjektet.

HVILLE bunnen

Jeg kunngjorde nettopp det nye Lær våren kurs, med fokus på det grunnleggende i vår 5 og vårstøvel 2:

>> KONTROLLER KURSET

$config[zx-auto] not found$config[zx-overlay] not found