REST API Discoverability og 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 vil fokusere på Oppdagbarheten til REST API, HATEOAS og praktiske scenarier drevet av tester.

2. Hvorfor gjøre API-et synlig

En APIs oppdagbarhet er et emne som ikke får nok fortjent oppmerksomhet. Som en konsekvens får veldig få API-er det riktig. Det er også noe som, hvis det gjøres riktig, kan gjøre API'et ikke bare RESTful og brukbart, men også elegant.

For å forstå oppdagbarhet, må vi forstå begrensningen for Hypermedia as the Engine Of Application State (HATEOAS). Denne begrensningen av en REST API handler om fullstendig oppdagbarhet av handlinger / overganger på en ressurs fra Hypermedia (Hypertext egentlig), som den eneste driver for applikasjonstilstand.

Hvis interaksjonen skal drives av API gjennom selve samtalen, konkret via Hypertext, kan det ikke foreligge dokumentasjon. Det ville tvinge klienten til å gjøre antakelser som faktisk er utenfor API-rammen.

For å konkludere, serveren skal være beskrivende nok til å instruere klienten hvordan man bruker API bare via Hypertext. I tilfelle en HTTP-samtale, kan vi oppnå dette gjennom Link Overskrift.

3. Oppdagbarhetsscenarier (drevet av tester)

Så hva betyr det at en REST-tjeneste kan oppdages?

Gjennom denne delen vil vi teste individuelle trekk ved oppdagbarhet ved hjelp av Junit, trygg og Hamcrest. Siden REST-tjenesten tidligere er sikret, må hver test først godkjennes før API-en konsumeres.

3.1. Oppdag gyldige HTTP-metoder

Når en REST-tjeneste forbrukes med en ugyldig HTTP-metode, skal svaret være en 405 METODE IKKE TILLATT.

APIen skal også hjelpe klienten med å oppdage gyldige HTTP-metoder som er tillatt for den aktuelle ressursen. For dette, vi kan bruke Tillate HTTP-overskrift i svaret:

@Test offentlig ugyldig nårInvalidPOSTIsSentToValidURIOfResource_thenAllowHeaderListsTheAllowedActions () {// Gitt streng uriOfExistingResource = restTemplate.createResource (); // Når svar res = givenAuth (). Post (uriOfExistingResource); // Deretter String allowHeader = res.getHeader (HttpHeaders.ALLOW); assertThat (allowHeader, AnyOf.anyOf (containString ("GET"), containString ("PUT"), containString ("DELETE"))); }

3.2. Oppdag URI for nyopprettet ressurs

Operasjonen med å opprette en ny ressurs bør alltid inkludere URI for den nyopprettede ressursen i svaret. For dette kan vi bruke plassering HTTP-topptekst.

Nå, hvis klienten gjør en GET på den URI-en, skal ressursen være tilgjengelig:

@Test public void whenResourceIsCreated_thenUriOfTheNewlyCreatedResourceIsDiscoverable () {// When Foo newResource = new Foo (randomAlphabetic (6)); Svar createResp = givenAuth (). ContentType ("application / json") .body (unpersistedResource) .post (getFooURL ()); Streng uriOfNewResource = createResp.getHeader (HttpHeaders.LOCATION); // Så svarrespons = givenAuth (). Header (HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE) .get (uriOfNewResource); Foo resourceFromServer = respons.body (). Som (Foo.class); assertThat (newResource, equalTo (resourceFromServer)); }

Testen følger et enkelt scenario: skape et nytt Foo ressurs, og deretter bruke HTTP-svaret for å oppdage URI der ressursen nå er tilgjengelig. Det gjør da også en GET på den URI for å hente ressursen og sammenligne den med originalen. Dette for å sikre at det ble lagret riktig.

3.3. Oppdag URI for å få alle ressursene av den typen

Når vi får noe spesielt Foo ressurs, bør vi kunne oppdage hva vi kan gjøre videre: vi kan liste opp alle tilgjengelige Foo ressurser. Dermed bør operasjonen med å hente en ressurs alltid inkludere URI hvor du skal få alle ressursene av den typen.

For dette kan vi igjen bruke Link Overskrift:

@Test offentlig ugyldig nårResourceIsRetrieved_thenUriToGetAllResourcesIsDiscoverable () {// Gitt streng uriOfExistingResource = createAsUri (); // Når svar getResponse = givenAuth (). Get (uriOfExistingResource); // Deretter String uriToAllResources = HTTPLinkHeaderUtil .extractURIByRel (getResponse.getHeader ("Link"), "collection"); Svar getAllResponse = givenAuth (). Get (uriToAllResources); assertThat (getAllResponse.getStatusCode (), er (200)); }

Merk at hele koden på lavt nivå for extractURIByRel - ansvarlig for å utvinne URI-ene ved å rel forhold vises her.

Denne testen dekker det kjedelige emnet Link Relations i REST: URI for å hente alle ressurser som bruker rel = ”samling” semantikk.

Denne typen koblingsrelasjon er ennå ikke standardisert, men er allerede i bruk av flere mikroformater og foreslått for standardisering. Bruk av ikke-standard koblingsrelasjoner åpner for diskusjonen om mikroformater og rikere semantikk i RESTful webtjenester.

4. Andre potensielle URI-er og mikroformater

Andre URI kan potensielt bli oppdaget via Link Overskrift, men det er bare så mye de eksisterende typene koblingsrelasjoner tillater uten å gå til en rikere semantisk markering, slik som å definere egendefinerte koblingsrelasjoner, Atom Publishing Protocol eller mikroformater, som vil være tema for en annen artikkel.

For eksempel skal klienten kunne oppdage URI for å opprette nye ressurser når han gjør en på en bestemt ressurs. Dessverre er det ingen koblingsrelasjon til modell skape semantikk.

Heldigvis er det en vanlig praksis at URI for opprettelse er den samme som URI for å FÅ alle ressursene av den typen, med den eneste forskjellen som er POST HTTP-metoden.

5. Konklusjon

Vi har sett hvordan en REST API er helt oppdagelig fra roten og uten forkunnskaper - som betyr at klienten er i stand til å navigere gjennom å gjøre en GET på roten. Fremover blir alle tilstandsendringer drevet av klienten ved hjelp av de tilgjengelige og oppdagelige overgangene som REST API gir i representasjoner (derav Representasjonsstatlig overføring).

Denne artikkelen dekket noen av egenskapene til oppdagbarhet i sammenheng med en REST-nettjeneste, diskuterte oppdagelse av HTTP-metoden, forholdet mellom opprett og få, oppdagelse av URI for å få alle ressurser osv

Implementeringen av alle disse eksemplene og kodebiter er tilgjengelig på GitHub. Dette er et Maven-basert prosjekt, så det skal være enkelt å importere og kjøre som det er.

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