REST API-vindbaarheid en HATEOAS

REST Top

Ik heb zojuist het nieuwe aangekondigd Leer de lente natuurlijk, gericht op de basisprincipes van Spring 5 en Spring Boot 2:

>> BEKIJK DE CURSUS

1. Overzicht

Dit artikel zal zich concentreren op Vindbaarheid van de REST API, HATEOAS en praktische scenario's aangestuurd door tests.

2. Waarom de API vindbaar maken?

Vindbaarheid van een API is een onderwerp dat niet genoeg welverdiende aandacht krijgt. Als gevolg hiervan doen maar heel weinig API's het goed. Het is ook iets dat, indien correct gedaan, de API niet alleen RESTful en bruikbaar maar ook elegant kan maken.

Om vindbaarheid te begrijpen, moeten we de beperking Hypermedia As The Engine Of Application State (HATEOAS) begrijpen. Deze beperking van een REST API gaat over de volledige vindbaarheid van acties / overgangen op een resource van Hypermedia (eigenlijk Hypertext), als de enige driver van applicatiestatus.

Als de interactie door de API moet worden aangestuurd via de conversatie zelf, concreet via Hypertext, dan kan er geen documentatie zijn. Dat zou de klant dwingen om aannames te doen die in feite buiten de context van de API vallen.

Tot slot, de server moet voldoende beschrijvend zijn om de cliënt te instrueren hoe hij de API moet gebruiken alleen via Hypertext. In het geval van een HTTP-gesprek kunnen we dit bereiken via de Koppeling koptekst.

3. Ontdekbaarheidsscenario's (aangestuurd door tests)

Dus wat betekent het dat een REST-service vindbaar is?

In deze sectie zullen we individuele kenmerken van vindbaarheid testen met Junit, gerustgesteld en Hamcrest. Omdat de REST-service eerder is beveiligd, moet elke test eerst worden geverifieerd voordat de API wordt gebruikt.

3.1. Ontdek de geldige HTTP-methoden

Wanneer een REST-service wordt gebruikt met een ongeldige HTTP-methode, moet het antwoord een 405-METHODE NIET TOEGESTAAN zijn.

De API moet de klant ook helpen de geldige HTTP-methoden te ontdekken die zijn toegestaan ​​voor die specifieke bron. Voor deze, we kunnen de Toestaan HTTP-header in het antwoord:

@Test openbare leegte whenInvalidPOSTIsSentToValidURIOfResource_thenAllowHeaderListsTheAllowedActions () {// Gegeven String uriOfExistingResource = restTemplate.createResource (); // When Response res = givenAuth (). Post (uriOfExistingResource); // Dan String allowHeader = res.getHeader (HttpHeaders.ALLOW); assertThat (allowHeader, AnyOf.anyOf (containsString ("GET"), containsString ("PUT"), containsString ("DELETE"))); }

3.2. Ontdek de URI van nieuw gecreëerde bron

De bewerking voor het maken van een nieuwe bron moet altijd de URI van de nieuw gemaakte bron in het antwoord bevatten. Hiervoor kunnen we de Plaats HTTP-koptekst.

Als de client nu een GET doet op die URI, zou de bron beschikbaar moeten zijn:

@Test openbare leegte whenResourceIsCreated_thenUriOfTheNewlyCreatedResourceIsDiscoverable () {// When Foo newResource = nieuwe Foo (randomAlphabetic (6)); Antwoord createResp = givenAuth (). ContentType ("application / json") .body (unpersistedResource) .post (getFooURL ()); String uriOfNewResource = createResp.getHeader (HttpHeaders.LOCATION); // Dan antwoordantwoord = gegevenAuth (). Header (HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE) .get (uriOfNewResource); Foo resourceFromServer = response.body (). As (Foo.class); assertThat (newResource, equalTo (resourceFromServer)); }

De test volgt een eenvoudig scenario: het creëren van een nieuw Foo resource en vervolgens het HTTP-antwoord gebruiken om de URI te ontdekken waar de resource nu beschikbaar is. Het doet dan ook een GET op die URI om de bron op te halen en te vergelijken met het origineel. Dit is om ervoor te zorgen dat het correct is opgeslagen.

3.3. Ontdek de URI om alle bronnen van dat type te KRIJGEN

Wanneer we iets speciaals krijgen Foo resource, zouden we moeten kunnen ontdekken wat we vervolgens kunnen doen: we kunnen alle beschikbare lijsten opsommen Foo middelen. De bewerking van het ophalen van een bron moet dus altijd in de reactie de URI bevatten waar alle bronnen van dat type vandaan moeten komen.

Hiervoor kunnen we weer gebruik maken van de Koppeling koptekst:

@Test openbare leegte whenResourceIsRetrieved_thenUriToGetAllResourcesIsDiscoverable () {// Gegeven String uriOfExistingResource = createAsUri (); // When Response getResponse = givenAuth (). Get (uriOfExistingResource); // Dan String uriToAllResources = HTTPLinkHeaderUtil .extractURIByRel (getResponse.getHeader ("Link"), "collectie"); Antwoord getAllResponse = givenAuth (). Get (uriToAllResources); assertThat (getAllResponse.getStatusCode (), is (200)); }

Merk op dat de volledige low-level code voor extractURIByRel - verantwoordelijk voor het extraheren van de URI's door rel relatie wordt hier getoond.

Deze test behandelt het netelige onderwerp van Link Relations in REST: de URI om alle bronnen op te halen gebruikt de rel = "collectie" semantiek.

Dit type linkrelatie is nog niet gestandaardiseerd, maar wordt al door verschillende microformats gebruikt en voorgesteld voor standaardisatie. Het gebruik van niet-standaard linkrelaties opent de discussie over microformats en rijkere semantiek in RESTful webservices.

4. Andere potentieel detecteerbare URI's en microformats

Andere URI's kunnen mogelijk worden ontdekt via het Koppeling koptekst, maar er is slechts zoveel dat de bestaande typen linkrelaties toestaan ​​zonder over te gaan op een rijkere semantische opmaak, zoals het definiëren van aangepaste linkrelaties, het Atom Publishing Protocol of microformats, waarover een ander artikel zal gaan.

De client moet bijvoorbeeld de URI kunnen ontdekken om nieuwe bronnen te maken bij het uitvoeren van een KRIJGEN op een specifieke bron. Helaas is er geen verband met het model creëren semantiek.

Gelukkig is het een standaardpraktijk dat de URI voor het maken dezelfde is als de URI om alle bronnen van dat type GET te krijgen, met als enige verschil de POST HTTP-methode.

5. Conclusie

We hebben gezien hoe een REST API volledig detecteerbaar is vanaf de root en zonder voorafgaande kennis - wat betekent dat de klant erin kan navigeren door een GET op de root uit te voeren. In de toekomst worden alle statuswijzigingen aangestuurd door de client met behulp van de beschikbare en vindbare overgangen die de REST API biedt in representaties (vandaar Representatieve staatsoverdracht).

Dit artikel behandelde enkele van de kenmerken van vindbaarheid in de context van een REST-webservice, en besprak de detectie van HTTP-methoden, de relatie tussen create en get, ontdekking van de URI om alle bronnen te krijgen, enz.

De implementatie van al deze voorbeelden en codefragmenten is beschikbaar op GitHub. Dit is een op Maven gebaseerd project, dus het zou gemakkelijk moeten kunnen worden geïmporteerd en uitgevoerd zoals het is.

REST onder

Ik heb zojuist het nieuwe aangekondigd Leer de lente natuurlijk, gericht op de basisprincipes van Spring 5 en Spring Boot 2:

>> BEKIJK DE CURSUS