El primer que farem serà desplegar el servei web que us proporcionem com a punt de partida i provar que funciona correctament. Desplegueu el projecte fent Run a NetBeans.
Projecte en estat final
En el següent enllaç teniu disponible el projecte en l’estat final:
Tot i que podeu descarregar-vos el projecte en l’estat final, sempre és millor que aneu fent vosaltres tots els passos partint del projecte en l’estat inicial de l’apartat. Recordeu que podeu utilitzar la funció d’importar per carregar els projectes a NetBeans.
El servei web RESTful que conté el projecte permet fer operacions sobre equips de futbol i els jugadors que els integren. Té implementades les operacions típiques CRUD amb els jugadors, una operació que mostra el llistat d’equips, una que ensenya els jugadors d’un equip i una altra que mostra les dades d’un equip.
Per fer l’exercici ens ficarem en la funcionalitat que permet consultar les dades d’un equip i la funcionalitat que permet llistar tots els jugadors.
Per consultar les dades d’un equip (per exemple, les dades del FC Barcelona), accediu amb un navegador a l’URL localhost:8080/springresthateoasioc/teams/1 i, si tot ha anat bé, veureu la representació JSON de l’equip consultat al navegador:
[{
"teamId":1,
"name":"F.C. Barcelona",
"foundationYear":"1899"
}]
Si ara voleu llistar els jugadors que formen part del FC Barcelona no ens queda més remei que consultar l’API del servei RESTful per veure que ho podem fer amb una petició GET
a /teams/{teamId}/players. Si ho feu accedint amb un navegador a l’URL localhost:8080/springresthateoasioc/teams/1/players veureu la llista de jugadors del FC Barcelona:
[
{"id":1,"name":"LionelMessi","goals":472,"age":29,"teamId":1},
{"id":2,"name":"Luis Suarez","goals":100,"age":29,"teamId":1}}
]
Amb aquesta aproximació apareixen dos problemes principals:
No tenim cap manera de saber com obtenir els jugadors d’un equip sense haver de consultar la seva
API.
Si la forma d’accedir (
API) als jugadors d’un equip canvia caldrà canviar
tots els clients que la utilitzaven.
Per solucionar aquestes dues problemàtiques apareix el concepte de HATEOAS.
De forma molt simplificada, podríem veure HATEOAS com un principi de disseny que obliga que, donat un punt d’entrada al servei, els clients han de ser capaços de descobrir tots els seus recursos basant-se únicament en respostes donades pel servidor.
A l’exemple que ens aplica, això vol dir que quan consultem la informació d’un equip el servidor ens ha de tornar també l’enllaç per consultar els seus jugadors; és a dir, la resposta JSON a la consulta de les dades d’un equip ha de ser similar a aquesta:
[{
"teamId":1,
"name":"F.C. Barcelona",
"foundationYear":"1899",
“players”: “http://localhost:8080/springresthateoasioc/teams/1/players”
}]
D’aquesta forma ja sabrem on i com anar a buscar els recursos relacionats (jugadors) amb el nostre recurs (equip) gràcies a la resposta del servidor en forma d’enllaç. Molts puristes diuen que una API no és realment RESTful si no segueix aquest principi de disseny.
Ara ja sabem què és HATEOAS i també que el nostre servei web no el segueix, però com ho podem fer dissenyar-lo seguint el principi HATEOAS? Aquí és on apareix un petit mòdul Spring anomenat Spring HATEOAS, que ens ajudarà a fer que el nostre servei respecti el principi HATEOAS.
Modifiqueu el pom.xml per afegir les dependències cap a Spring HATEOAS, afegint les següent línies al fitxer pom.xml:
<dependency>
<groupId>org.springframework.hateoas</groupId>
<artifactId>spring-hateoas</artifactId>
<version>0.8.0.RELEASE</version>
</dependency>
Recarregueu el pom.xml fent clic amb el botó dret damunt el nom del projecte i prement l’opció Reload POM.
Spring HATEOAS tan sols imposa una restricció: els recursos que tornem a la resposta han d’estendre de la classe org.springframework.hateoas.ResourceSupport
. Simplement fent això ja podrem afegir al recurs els enllaços que permetran als clients fer la navegació.
El recurs que volem que torni l’enllaç amb la consulta dels jugadors de l’equip és l’objecte del domini Team, que és el que torna la consulta de la informació d’un equip. Obriu la classe Team
del paquet cat.xtec.ioc.domain
i feu que estengui de ResourceSupport
:
public class Team extends ResourceSupport
Ara el que hem de fer és modificar el mètode del servei web que torna les dades d’un equip per incloure l’enllaç a la resposta que permetrà consultar els jugadors de l’equip. Per fer-ho obriu la classe TeamsController
del paquet cat.xtec.ioc.controller
i canvieu el codi del mètode getById
pel següent:
@RequestMapping(value = "/teams/{id}", method = RequestMethod.GET)
public @ResponseBody
Team getById(@PathVariable int id) {
Team team = this.teamRepository.get(id);
final Link link = linkTo(methodOn(PlayerController.class).getTeamPlayers(team.getTeamId())).withRel("players");
team.add(link);
return team;
}
El que fem és crear un enllaç que apunta al recurs que donaria com a resultat la invocació al mètode getTeamPlayers
del controlador PlayerController
.
Fixeu-vos que tant methodOn
com linkToCodi
són mètodes estàtics de la classe org.springframework.hateoas.mvc.ControllerLinkBuilder
; per poder-los utilitzar cal que afegim a la classe TeamsController
els import corresponents:
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo;
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.methodOn;
Ara ja tan sols ens queda tornar a desplegar el servei web per veure si es comporta com volem. Desplegueu-lo fent Run a NetBeans i comproveu que la representació JSON de l’equip ara incorpora un enllaç per consultar els seus jugadors.
Per fer-ho accediu a l’URL localhost:8080/springresthateoasioc/teams/1 amb un navegador i, si tot ha anat bé, veureu que la resposta JSON incorpora l’enllaç que volíem:
[{
"teamId":1,
"name":"F.C.Barcelona",
"foundationYear":"1899",
"links":[{"rel":"players","href":"http://localhost:8080/springresthateoasioc/teams/1/players"}]
}]
Amb HATEOAS hem aconseguit solucionar els dos problemes principals que tenia el nostre servei web quan no seguia els principis HATEOAS:
Ara ja sabem com obtenir els jugadors d’un equip sense haver de consultar la seva
API.
Si la forma d’accedir (
API) als jugadors d’un equip canvia, l’enllaç que tornem canviarà i no caldrà modificar els clients que la utilitzaven.