5. Spring Haetoas
1. HATEOAS
Hateoas (Hypermedia as the engine of application state) és un principi d'API RESTful definit per Roy Fielding. Principalment significa que el client pot moure's per tota l'aplicació només des d'URI's generals en format hipermèdia. El principi implica que l'API ha de guiar el client a través de l'aplicació retornant informació rellevant sobre els següents passos potencials, juntament amb cada resposta.
Per a la connexió entre el servidor i el client, Fielding defineix aquestes quatre característiques:
- Identificació única de tots els recursos: tots els recursos han de poder ser identificats amb un URI (Identificador de Recurs Únic).
- Interacció amb recursos a través de representacions: Si un client necessita un recurs, el servidor li envia una representació (per exemple, HTML, JSON o XML) perquè el client pugui modificar o eliminar el recurs original.
- Missatges explícits: cada missatge intercanviat entre el servidor i el client ha de contenir totes les dades necessàries per entendre's mútuament.
- HATEOAS: Aquest principi també integra una API REST. Aquesta estructura basada en hipermèdia facilita als clients l'accés a l'aplicació, ja que no necessiten conèixer res més sobre la interfície per poder accedir-hi i navegar-hi.
HATEOAS és, en resum, una de les propietats més bàsiques de les API REST i, com a tal, essencial en qualsevol servei REST.
Un valor retornat sense HATEOAS, amb dades d'un client:
Tingues en compte que:
- Hem obtingut totes les dades del client
- No sabem com obtenir dades de camps relacionats específics, com
DireccionoCuenta. Estan ahí però no sabem com obtenir-les
La mateixa sol·licitud amb HATEOAS:
Com pots veure:
- Només s'envien les dades d'un client
- Tenim enllaços, amb URI's clares per obtenir informació específica d'aquest client
i el més important Si el servidor canvia la seva estructura, enviarà enllaços actualitzats, i el client funcionarà sense cap problema
2. Afegint HATEOAS
2.1. Llibrerires
Atenció
En aquest text, afegirem capacitats HATEOAS a una API RESTful desenvolupada al llarg de la unitat.
Només necessitem afegir aquesta dependència al nostre pom.xml, suposant que hem utilitzat un projecte iniciador de Spring:
| XML | |
|---|---|
i ja està.
2.2. Wrappers (Envoltoris)
2.2.1. Punt d'inici
Recorda el que hem fet en el nostre projecte inicial:
- Classes Model o DAO → preparades per guardar informació a la base de dades. Estan anotades amb Hibernate i són la base dels nostres repositoris. Per exemple,
Cliente. - Classes DTO → preparades per transferir dades des del nostre model i cap a aquest.
- Aquestes classes encapsulen les DAO (afegint o eliminant camps).
- Aquestes classes tenen mètodes per convertir entre DAO i DTO.
- És el servei qui realitza la conversió.
- El client ens enviarà informació en aquestes classes DTO.
- Aquestes classes poden ser utilitzades tant per una API Rest com per una aplicació web MVC.
2.2.2. Envoltori HATEOAS
Necessitem definir una nova classe per embolicar la nostra resposta HATEOAS.
Partint dels DTO's, conté tota la informació d'una classe, pròpia i relacionada (Client més Direcció més Comptes). Amb HATEOAS, com hem mostrat recentment, només necessitem la informació pròpia del Client i necessitem generar enllaços a entitats relacionades. Llavors, necessitem afegir a la informació del client la capacitat de generar i emmagatzemar enllaços. La classe que ho permet és RepresentationModel<base_class> (documentació completa aquí). Això afegirà a les nostres classes:
- Una estructura per a guadar links
- Mètodes per afegir, comprovar i retornar links
Per tal de fer-ho
Important
- Com que tenim una API base que funciona amb
ClienteDTO, hem creat aquesta classe envoltori a partir d'ella. - Com que HATEOAS és només un format de resposta, pots crear-lo a partir de
Clientecom a classe base, però has de definir el teu servei per retornarClientetambé. - És molt important crear un mètode de conversió
fromClienteDTO2HATEOAS, que inclogui els camps necessaris.
Llavors, utilitzarem el mètode add(Link) en el nostre envoltori ClienteHATEOAS per afegir tants Link com sigui necessari.
3. Links
Ara, la pregunta és com generar els nostres objectes Link en les nostres classes envoltori. Podríem fer-ho de manera creativa, manipulant camins en cadenes de text i composant amb mètodes complicats de subcadena i concatenació.
Però com que sabem quin mètode es crida per a cada referència, és millor crear enllaços obtenint referències al camí des dels mateixos mètodes. Per fer-ho, hem d'utilitzar aquests mètodes i crides estàtiques:
linkTo→ mètode estàtic que crea unLinkdes demethodOn(class)→ cerca en una classe de controlador un mètode.methodName(args)→ obté una crida real per a aquest mètode- I per etiquetar l'enllaç:
.withSelfRel()→ crea un enllaç anomenatself.withRel(String Link)→ crea un enllaç amb el nom donat.
Exemples del nostre Cliente controller en la següent secció
3.1. Self links
| Java | |
|---|---|
Aquest exemple:
- Carrega un
ClienteDTOdelClienteServiceactual. - Després busca a la classe
ClienteControllerun mètode anomenatshowClienteById. - Fa una crida interna i cerca el camí i vincula l'argument al camí (recordes
@PathVariable?) - Finalment, obté el camí (ruta) complet amb l'argument i l'emmagatzema en el Link amb la referència
self
El resultat serà alguna cosa així:
3.2. Referenciant links
| Java | |
|---|---|
Aquest exemple:
- Carrega un
ClienteDTOdelClienteServiceactual. - Després busca a la classe
CuentaControllerun mètode anomenatlistCuentasCliente. - Fa una crida interna i cerca el camí i vincula l'argument al camí (recordes
@PathVariable?) - Finalment, obté el camí (ruta) complet amb l'argument i l'emmagatzema en el Link amb la referència
self
El resultat serà alguna cosa així:
3.3. Afegint enllaços al nostre envoltori i exemple complet
Un cop hem creat els enllaços, necessitem afegir-los a la nostra última classe envoltori. Simplement utilitzarem el mètode add() per fer-ho. En el següent mètode, es rep un embolcall ClienteHATEOAS (amb només dades de ClienteDTO) i s'afegeixen tants enllaços com vulguem:
El mètode del controlador per obtenir un Cliente serà (comentat):
i el resultat serà alguna cosa així:
4. Treball pendent
Ara, fent una petició simple a un Cliente tenim accès a tota la informació i següents accions disponibles en les dades de la resposta
Això permet al servidor poder evolucionar sense tindre que modificar eels clients que li fan peticions, ja que qualssevol modificació sera inmediatamnet notificada als usuaris de les API en les pròpies respostes.
Ara et toca a tu completar el projecte desenvoluat afegint les classes necessàries i afegint el HATEOAS als teus models.