Otkrivenost REST API-ja i HATEOAS

OSTALO Vrh

Upravo sam najavio novo Uči proljeće tečaj, usredotočen na osnove Spring 5 i Spring Boot 2:

>> PROVJERITE TEČAJ

1. Pregled

Ovaj će se članak usredotočiti na Otkrivenost REST API-ja, HATEOAS i praktični scenariji vođeni testovima.

2. Zašto API učiniti vidljivim?

Otkrivenost API-ja tema je koja ne dobiva dovoljno zasluženu pozornost. Kao posljedica toga, vrlo malo API-ja to uspije. To je također nešto što, ako se pravilno izvede, može API učiniti ne samo OTPORNIM i upotrebljivim, već i elegantnim.

Da bismo razumjeli mogućnost otkrivanja, moramo razumjeti ograničenje Hypermedia kao pokretača stanja primjene (HATEOAS). Ovo ograničenje REST API-ja odnosi se na potpunu otkrivenost radnji / prijelaza na resursu iz Hypermedia (zapravo Hypertext), kao jedinog pokretača stanja aplikacije.

Ako API treba voditi interakciju kroz sam razgovor, konkretno putem Hiperteksta, tada ne može biti dokumentacije. To bi natjeralo klijenta na pretpostavke koje su zapravo izvan konteksta API-ja.

U zaključku, poslužitelj bi trebao biti dovoljno opisan da klijenta uputi kako se koristi API samo putem hiperteksta. U slučaju HTTP razgovora, to bismo mogli postići putem Veza Zaglavlje.

3. Scenariji otkrivanja (na temelju testova)

Pa što znači da se REST usluga može otkriti?

Kroz ovaj odjeljak testirat ćemo pojedinačne osobine otkrića pomoću Junita, budite sigurni i Hamcrest. Budući da je REST usluga prethodno osigurana, svaki test prvo mora provjeriti autentičnost prije konzumiranja API-ja.

3.1. Otkrijte valjane HTTP metode

Kada se REST usluga koristi s nevažećom HTTP metodom, odgovor bi trebao biti METODA 405 KOJA NIJE DOZVOLJENA.

API bi također trebao pomoći klijentu da otkrije važeće HTTP metode koje su dopuštene za taj određeni resurs. Za ovo, možemo koristiti Dopustite HTTP zaglavlje u odgovoru:

@Test public void whenInvalidPOSTIsSentToValidURIOfResource_thenAllowHeaderListsTheAllowedActions () {// Dat je niz uriOfExistingResource = restTemplate.createResource (); // Kada je odgovor res = givenAuth (). Post (uriOfExistingResource); // Zatim String allowHeader = res.getHeader (HttpHeaders.ALLOW); assertThat (allowHeader, AnyOf.anyOf (containsString ("GET"), containsString ("PUT"), containsString ("DELETE"))); }

3.2. Otkrijte URI novostvorenog resursa

Postupak stvaranja novog resursa uvijek treba uključiti URI novostvorenog resursa u odgovoru. Za to možemo koristiti Mjesto HTTP zaglavlje.

Ako klijent izvrši GET na tom URI-ju, resurs bi trebao biti dostupan:

@Test public void whenResourceIsCreated_thenUriOfTheNewlyCreatedResourceIsDiscoverable () {// When Foo newResource = new Foo (randomAlphabetic (6)); Odgovor createResp = givenAuth (). ContentType ("application / json") .body (unpersistedResource) .post (getFooURL ()); Niz uriOfNewResource = createResp.getHeader (HttpHeaders.LOCATION); // Tada je odgovor odgovora = givenAuth (). Zaglavlje (HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE) .get (uriOfNewResource); Foo resourceFromServer = response.body (). As (Foo.class); assertThat (newResource, jednakTo (resourceFromServer)); }

Test slijedi jednostavan scenarij: stvaranje novog Foo resursa, a zatim pomoću HTTP odgovora otkrijte URI gdje je Resurs sada dostupan. Zatim također vrši GET na tom URI-ju za dohvaćanje resursa i uspoređuje ga s izvornikom. Time se osigurava da je ispravno spremljeno.

3.3. Otkrijte URI da biste DOBILI sve resurse te vrste

Kad DOBIJEMO bilo što određeno Foo resursa, trebali bismo moći otkriti što možemo dalje: možemo navesti sve dostupne Foo resursi. Dakle, operacija dohvaćanja resursa uvijek treba u svom odgovoru uključivati ​​URI gdje dobiti sve resurse te vrste.

Za to možemo ponovno koristiti Veza Zaglavlje:

@Test public void whenResourceIsRetrieved_thenUriToGetAllResourcesIsDiscoverable () {// Dat je niz uriOfExistingResource = createAsUri (); // Kada je odgovor getResponse = givenAuth (). Get (uriOfExistingResource); // Zatim String uriToAllResources = HTTPLinkHeaderUtil .extractURIByRel (getResponse.getHeader ("Link"), "collection"); Odgovor getAllResponse = givenAuth (). Get (uriToAllResources); assertThat (getAllResponse.getStatusCode (), je (200)); }

Imajte na umu da puni kod niske razine za ekstraktURIByRel - odgovoran za izdvajanje URI-ja rel ovdje je prikazana relacija.

Ovaj test pokriva trnovitu temu Veza odnosa u REST-u: URI za dohvaćanje svih resursa koristi rel = "zbirka" semantika.

Ova vrsta odnosa veza još nije standardizirana, ali već je u upotrebi nekoliko mikroformata i predložena za standardizaciju. Korištenje nestandardnih odnosa veza otvara raspravu o mikroformatima i bogatijoj semantici u RESTful web uslugama.

4. Ostali potencijalni URI-ji i mikroformati koji se mogu otkriti

Ostali URI-i potencijalno bi mogli biti otkriveni putem Veza Zaglavlje, ali postoje samo toliko postojeće vrste veza veza koje omogućuju bez prelaska na bogatiju semantičku oznaku, poput definiranja prilagođenih odnosa veza, Atom Publishing Protocol ili mikroformata, što će biti tema drugog članka.

Na primjer, klijent bi trebao biti u mogućnosti otkriti URI za stvaranje novih resursa kada radi DOBITI na određenom Resursu. Nažalost, ne postoji veza u odnosu na model stvoriti semantika.

Srećom je uobičajena praksa da je URI za izradu isti kao URI za DOBIVANJE svih resursa te vrste, s jedinom razlikom u POST HTTP metodi.

5. Zaključak

Vidjeli smo kako je REST API u potpunosti moguće otkriti iz korijena i bez prethodnog znanja - što znači da je klijent sposoban njime se kretati radeći GET na korijenu. Krećući se prema naprijed, sve promjene stanja pokreće klijent koristeći dostupne i otkrivene prijelaze koje REST API pruža u prikazima (dakle Reprezentativni državni prijenos).

Ovaj je članak obuhvatio neke osobine otkrića u kontekstu REST web usluge, raspravljajući o otkrivanju HTTP metode, odnosu između stvaranja i dobivanja, otkrivanju URI-ja za dobivanje svih resursa itd.

Implementacija svih ovih primjera i isječaka koda dostupna je na GitHubu. Ovo je projekt zasnovan na Mavenu, pa bi ga trebalo lako uvesti i pokrenuti kakav jest.

OSTALO dno

Upravo sam najavio novo Uči proljeće tečaj, usredotočen na osnove Spring 5 i Spring Boot 2:

>> PROVJERITE TEČAJ

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