HATEOAS a tavaszi Pihenés szolgáltatásért

REST felső

Most jelentettem be az újat Tanulj tavaszt tanfolyam, amelynek középpontjában az 5. tavasz és a tavaszi bakancs 2 alapjai állnak:

>> ELLENŐRIZZE A FOLYAMATOT

1. Áttekintés

Ez a cikk a a felfedezhetőség megvalósítása egy tavaszi REST szolgáltatásban és a HATEOAS korlátozásának teljesítéséről.

Ez a cikk a Spring MVC-re összpontosít. Az Intro to Spring HATEOAS cikkünk leírja a HATEOAS használatát a tavaszi rendszerindításban.

2. A felfedezhetőség függetlenítése az események révén

A felfedezhetőséget, mint a webréteg külön szempontját vagy gondját, el kell választani a vezérlőtől a HTTP kérés kezelése. Ebből a célból a Vezérlő eseményeket indít el minden olyan művelet esetében, amely a reakció további manipulációját igényli.

Először hozzuk létre az eseményeket:

public class SingleResourceRetrieved kiterjeszti az ApplicationEvent {private HttpServletResponse választ; public SingleResourceRetrieved (Object source, HttpServletResponse response) {szuper (forrás); ez.válasz = válasz; } public HttpServletResponse getResponse () {return response; }} public class ResourceCreated kiterjeszti az ApplicationEvent {private HttpServletResponse választ; privát hosszú idOfNewResource; public ResourceCreated (Object source, HttpServletResponse response, long idOfNewResource) {super (forrás); ez.válasz = válasz; this.idOfNewResource = idOfNewResource; } public HttpServletResponse getResponse () {return response; } public long getIdOfNewResource () {return idOfNewResource; }}

Azután, a vezérlő, 2 egyszerű művelettel - id szerint találni és teremt:

@RestController @RequestMapping (value = "/ foos") nyilvános osztályú FooController {@Autowired private ApplicationEventPublisher eventPublisher; @Autowired privát IFooService szolgáltatás; @GetMapping (value = "foos / {id}") public Foo findById (@PathVariable ("id") Long id, HttpServletResponse response) {Foo resourceById = Preconditions.checkNotNull (service.findOne (id)); eventPublisher.publishEvent (új SingleResourceRetrieved (ez, válasz)); return resourceById; } @PostMapping @ResponseStatus (HttpStatus.CREATED) public void create (@RequestBody Foo erőforrás, HttpServletResponse válasz) {Preconditions.checkNotNull (erőforrás); Long newId = service.create (erőforrás) .getId (); eventPublisher.publishEvent (new ResourceCreated (this, response, newId)); }}

Ezután tetszőleges számú független hallgatóval kezelhetjük ezeket az eseményeket. Ezek mindegyike a saját egyedi esetére összpontosíthat, és segíthet az általános HATEOAS-korlát teljesítésében.

A hallgatók legyenek a hívásverem utolsó objektumai, és nincs szükség közvetlen hozzáférésre; mint ilyenek nem nyilvánosak.

3. Egy újonnan létrehozott erőforrás URI-jának felfedezhetővé tétele

Amint azt a HATEOAS-ról szóló előző bejegyzés egy új erőforrás létrehozásának műveletének vissza kell adnia az erőforrás URI-ját a Elhelyezkedés HTTP fejléc a válasz.

Ezt egy hallgató segítségével kezeljük:

@Component class ResourceCreatedDiscoverabilityListener implementálja az ApplicationListener {@Override public void onApplicationEvent (ResourceCreated resourceCreatedEvent) {Preconditions.checkNotNull (resourceCreatedEvent); HttpServletResponse response = resourceCreatedEvent.getResponse (); hosszú idOfNewResource = resourceCreatedEvent.getIdOfNewResource (); addLinkHeaderOnResourceCreation (válasz, idOfNewResource); } void addLinkHeaderOnResourceCreation (HttpServletResponse válasz, hosszú idOfNewResource) {URI uri = ServletUriComponentsBuilder.fromCurrentRequestUri (). elérési út ("/ {idOfNewResource}"). buildAndExpand (idOfNewResource) .toUri (); response.setHeader ("Hely", uri.toASCIIString ()); }}

Ebben a példában felhasználjuk a ServletUriComponentsBuilder - amely segít az aktuális Kérés használatában. Így nincs szükségünk semmire sem, és egyszerűen statikusan hozzáférhetünk ehhez.

Ha az API visszatérne ResponseEntity - használhatnánk a Elhelyezkedés támogatás.

4. Egyetlen forrás megszerzése

Egyetlen erőforrás lekérésekor az ügyfélnek képesnek kell lennie felfedezni az URI-t az összes erőforrás megszerzéséhez ilyen típusú:

@Component osztály SingleResourceRetrievedDiscoverabilityListener implementálja az ApplicationListener {@Orride public void onApplicationEvent (SingleResourceRetrieved resourceRetrievedEvent) {Preconditions.checkNotNull (resourceRetrievedEvent); HttpServletResponse response = resourceRetrievedEvent.getResponse (); addLinkHeaderOnSingleResourceRetrieval (kérés, válasz); } void addLinkHeaderOnSingleResourceRetrieval (HttpServletResponse válasz) {String requestURL = ServletUriComponentsBuilder.fromCurrentRequestUri (). build (). toUri (). toASCIIString (); int positionOfLastSlash = requestURL.lastIndexOf ("/"); Karakterlánc uriForResourceCreation = requestURL.substring (0, positionOfLastSlash); String linkHeaderValue = LinkUtil .createLinkHeader (uriForResourceCreation, "gyűjtemény"); response.addHeader (LINK_HEADER, linkHeaderValue); }}

Vegye figyelembe, hogy a linkkapcsolat szemantikája a "Gyűjtemény" relációs típus, amelyet több mikroformátumban határoztak meg és használtak, de még nem szabványosítottak.

A Link fejléc az egyik leggyakrabban használt HTTP fejléca felfedezhetőség céljából. A fejléc létrehozásának segédprogramja elég egyszerű:

public class LinkUtil {public static String createLinkHeader (String uri, String rel) {return "; rel = \" "+ rel +" \ ""; }}

5. Felfedezhetőség a gyökérnél

A gyökér a teljes szolgáltatás belépési pontja - ez az, amellyel az ügyfél kapcsolatba lép az API első használatakor.

Ha a HATEOAS-korlátozást figyelembe kell venni és végre kell hajtani, akkor itt kell elindulnia. Ebből kifolyólag a rendszer összes fő URI-jának a gyökérből kell felfedezhetőnek lennie.

Most nézzük meg ennek vezérlőjét:

@GetMapping ("/") @ResponseStatus (érték = HttpStatus.NO_CONTENT) public void adminRoot (végleges HttpServletRequest kérés, végleges HttpServletResponse válasz) {String rootUri = request.getRequestURL (). ToString (); URI fooUri = új UriTemplate ("{rootUri} {erőforrás}"). Expand (rootUri, "foos"); String linkToFoos = LinkUtil.createLinkHeader (fooUri.toASCIIString (), "gyűjtemény"); response.addHeader ("Link", linkToFoos); }

Ez természetesen a koncepció szemléltetése, egyetlen, URI mintára összpontosítva Foo Erőforrások. A valódi megvalósításnak hasonlóan hozzá kell adnia az URI-kat az összes, az ügyfél számára közzétett erőforráshoz.

5.1. A felfedezhetőség nem az URI-k megváltoztatásáról szól

Ez ellentmondásos kérdés lehet - egyrészt a HATEOAS célja, hogy az ügyfél felfedezze az API URI-ját, és ne támaszkodjon kemény kódolású értékekre. Másrészt - a web nem így működik: igen, felfedezik az URI-kat, de könyvjelzővel is ellátják őket.

Finom, de fontos megkülönböztetés az API fejlődése - a régi URI-knak továbbra is működniük kell, de minden ügyfélnek, aki felfedezi az API-t, fel kell fedeznie az új URI-kat - ami lehetővé teszi az API dinamikus változását, és a jó kliensek akkor is jól működnek, ha a API-változtatások.

Összegzésképpen - csak azért, mert a RESTful webszolgáltatás összes URI-ját hűvös URI-nak kell tekinteni (és a hűvös URI-k nem változnak) - ez nem azt jelenti, hogy a HATEOAS-korlátozás betartása nem rendkívül hasznos az API fejlesztésekor.

6. A felfedezhetőség figyelmeztetései

Ahogyan az előző cikkek körüli vitákból kiderül, a felfedezhetőség első célja, hogy minimálisan vagy egyáltalán nem használja a dokumentációt és az ügyfél megtanulja és megérti az API használatát a kapott válaszokon keresztül.

Valójában ezt nem szabad ilyen elrugaszkodott ideálnak tekinteni - így használjuk fel minden új weboldalt - mindenféle dokumentáció nélkül. Tehát, ha a koncepció a REST összefüggésében problematikusabb, akkor technikai megvalósításról van szó, nem pedig arról, hogy lehetséges-e vagy sem.

Ennek ellenére technikailag még mindig távol állunk a teljesen működő megoldástól - a specifikáció és a kerettámogatás még fejlődik, és emiatt kompromisszumokat kell kötnünk.

7. Következtetés

Ez a cikk a felfedezhetőség néhány tulajdonságának megvalósítását ismertette a RESTful szolgáltatás keretében a Spring MVC-vel, és a gyökérben a felfedezhetőség fogalmát érintette.

Ezeknek a példáknak és kódrészleteknek a megvalósítása megtalálható a GitHub-on - ez egy Maven-alapú projekt, ezért könnyen importálhatónak és futtathatónak kell lennie.

REST alsó

Most jelentettem be az újat Tanulj tavaszt tanfolyam, amelynek középpontjában az 5. tavasz és a tavaszi bakancs 2 alapjai állnak:

>> ELLENŐRIZZE A FOLYAMATOT