Presentation sur la contrainte d'architecture HATEOAS et comment le framework Spring nous facilite son implementation.
Source code : https://github.com/YoannBuch/simple-spring-restbucks
Fait par l'equipe de http://findtheflow.io, un outil qui permet d'analyser et visualiser des executions d'applications Java.
2. Qui sommes nous ?
➔ 2 développeurs
➔ Lancent une entreprise autour d’un outil de développement
http://findtheflow.io
➔ Focalisent sur la visualisation et analyse des exécutions de programmes
➔ Utilisent de nombreux projets de Spring : Boot, MVC, HATEOAS,
Websocket, Integration, Batch, etc.
7. Modèle de maturité REST
source: http://martinfowler.com/articles/richardsonMaturityModel.html
Utiliser HTTP
Modélisation en
resources
CRUD opération
HATEOAS
8. Notre exemple d’application
Construire une API
Consulter le menu
Commander des boissons
Payer la commande
Vérifier le statut de préparation de commande
...
R E S T B U C K S
Source: “REST in Practice: Hypermedia and Systems Architecture”
9. Level 0: POX
Une URI, une methode
SOAP, XML RPC, POX
Request Response
POST /coffeeService HTTP/1.1
Content-Type: application/xml
<request xmlns=”http://restbucks.com”>
<placeOrder>
<customer>Mike</customer>
<location>takeAway</location>
<items>...</items>
</placeOrder>
…
</request>
HTTP/1.1 200 OK
Content-Type: application/xml
<response xmlns=”http://restbucks.com”>
<success>true</success>
<orderConfirmation>
<orderId>1234</orderId>
</orderConfirmation>
<error/>
</response>
10. Level 1: Resources
URI unique pour chaque ressource
Un seul verbe HTTP sans sémantique
Request Response
POST /orders HTTP/1.1
Content-Type: application/xml
<orderRequest>
<operation>create</operation>
<customer>Mike</customer>
<location>takeAway</location>
<items>...</items>
…
</orderRequest>
HTTP/1.1 200 OK
Content-Type: application/xml
<orderResponse>
<success>true</success>
<orderId>1234</orderId>
<error/>
</orderResponse>
11. Level 2: HTTP verbs
Multiples URIs, multiples verbes
Status code
Request Response
POST /orders HTTP/1.1
Content-Type: application/xml
<order>
<customer>Mike</customer>
<location>takeAway</location>
<items>...</items>
…
</order>
GET /orders/1234
PUT /orders/1234
DELETE /orders/1234
HTTP/1.1 201 CREATED
Content-Type: application/xml
Location: http://restbucks.com/orders/1234
<order>
<customer>Mike</customer>
<location>takeAway</location>
<items>...</items>
<status>payment-expected</status>
</order>
12. Hypermedia As The Engine Of Application State
Level 3 : HATEOAS
protocole Objectif
état
Transfert des liens
dans des ressources
13. Level 3: HATEOAS
Submitted Paid
Canceled
Preparing Completed
place
update
cancel
pay
check status
deliver
planned
Transition d’états d’une commande
HATEOAS => Définir les transitions d’états dans la représentation des ressources
17. Hypermedia et Spring : Spring HATEOAS
Introduit concepts de ressources et liens
Resource(s), ResourceSupport, Link
Facilite la génération d’URIs
linkTo et methodOn
Serialize au format HAL (XML et JSON)
Facilite la consommation des liens
HalkLinkDiscoverer, Traverson
Facilite l’assemblage des ressources
ResourceAssembler
18. Liens
Link link = new Link("http://localhost:8080/something");
assertThat(link.getHref(), is("http://localhost:8080/something"));
assertThat(link.getRel(), is(Link.SELF));
Link link = new Link("http://localhost:8080/something", "my-rel");
assertThat(link.getHref(), is("http://localhost:8080/something"));
assertThat(link.getRel(), is("my-rel"));
Source : http://docs.spring.io/spring-hateoas/docs/0.19.0.RELEASE/reference/html
20. Générer des URIs
Link link = linkTo(methodOn(PersonController.class).show(2L)).withSelfRel();
assertThat(link.getHref(), is("http://localhost:8080//people/2")));
Découvrir et récuperer des liens
String content = "{'_links' : { 'foo' : { 'href' : '/foo/bar' }}}";
LinkDiscoverer discoverer = new HalLinkDiscoverer();
Link link = discoverer.findLinkWithRel("foo", content);
assertThat(link.getHref(), is("/foo/bar"));
22. Consommer une API hypermedia - JavaScript
// traverson
traverson.json.from("http://api.github.com")
.newRequest()
.follow('repository_url', 'branches_url')
.withTemplateParameters({
owner: 'spring-projects',
repo: 'spring-hateoas',
branch: 'master'
}).getResource(function(err, resource) {
if (err) { console.log(err); return; }
console.log(resource);
// do something else
})
})
// jquery ajax
$.get("http://api.github.com", function(resource) {
var uri = nextUri(resource, 'repository_url')
uri = uri.replace(/{owner}/, 'spring-projects')
uri = uri.replace(/{repo}/, 'spring-hateoas')
$.get(uri, function(resource) {
uri = nextUri(resource, 'branches_url')
uri = uri.replace(/{/branch}/, '/master')
$.get(uri, function(resource) {
console.log(resource);
// do something else
})
})
})
function nextUri(resource, link) {
return resource[link]
}
https://github.com/basti1302/traverson-hal
23. HATEOAS
API explorable et auto-descriptive
➔Meilleure adoption de l’API
➔Mettre en avant des nouvelles fonctionnalités
Logique client simple
➔Pas d’URIs en dur
➔Client suit un protocole
Couplage faible entre serveur et client
➔Client résistant au changement des URIs
➔Moins de dépendences aux URI templates ou
langages de définition (ex. WSDL, WADL)
24. Pour aller plus loin
Livre : “REST in Practice: Hypermedia and Systems Architecture”
Spring Restbucks (et notre notre version simplifiee)
Bons examples en production (FoxyCart, PayPal, etc.)
Spring Data REST
HAL Browser
Spring REST Docs
CURIEs
Traitement des erreurs avec vnd.error
ice breakers:
rappeler le talk de Spring Cloud?
demander a l’audience leur niveau avec REST et HATEOAS
ha-TAY-oh-ahss
HTML supports hypermedia (urls and forms)
When browsing the Web, we’re used to navigating between pages by clicking links or completing and submitting forms.
In a typical e-commerce solution such as amazon.com, the server generates web pages with links on them that corral the user through the process of selecting goods, purchasing, and arranging delivery.
consulter les articles -> ajouter au panier -> passer la commande (livraison, paiement, confirmation)
un point d’entree, suivre les etapes;
A quoi ça ressemble dans une intéraction entre machines?
https://api.github.com
https://api.github.com/users/spring-projects
https://api.github.com/repos/spring-projects/spring-hateoas
= ou se situe l’hypermedia dans architecture REST (Representational State Transfer)
http://martinfowler.com/articles/richardsonMaturityModel.html
Level 0:
une URI, une methode
SOAP, XML RPC, POX
blackbox
Level 1:
Chaque ressource est identifiée par une URI unique
une seule verbe HTTP qui n’a pas de sémantique
Level 2:
Multiples URIs, multiples verbes + status code
CRUD
Level 3:
ressources sont auto-descriptives
RESTful
= HATEOAS c’est quoi
hypermedia as the engine of application state
hypermedia: a hypermedia system is characterized by the transfer of links in the resource representations exchanged by the participants in an application protocol
état d’application: objectif applicatif | protocol des interactions | snapshot d’execution du protocol
ex. restbucks: commander un café | initier une commande, payer |
L’etat / la représentation d’une ressource est composé de:
les valeurs de ses attributs
les liens vers d’autres ressources
les liens representant une transition possible vers un état futur de la ressource actuelle
diagramme etat
diagramme complet pour la ressource commande
standard = facile a implementer et consommer
format = liens vers ressources + annotations semantiques (comment interpreter la ressource)
rel = what is this link?
method, doc contextuelle, accepts/produces media types
http://ionwg.github.io/draft-ion.html
Demo
Level 2:
Source code
Creation commande
PB: faut connaitre le lien
Location header
Cancel
Payment
Montrer que c’est pas explorable, pas de protocole
Level 3:
Browser
Montrer ce que l’on veut obtenir
Source code
Ressource racine
Creation ressource
Creation liens avec linkTo
Creation liens en fonction de l’etat de la ressource
REST Client
payment scenario
Automated testing
suivi du protocole
trouver liens dans les reponses
jsonpath
utilisation de RestTemplate (et non Traverson)
Traverson ne supporte que GET => RestTemplate
jquery ajax: recuperer la resource, parser l’uri, remplacer les parametres puis répéter le même process => callback pyramid
traverson: suivre une séquence de liens jusqu’à la resource target
éviter callback pyramid
https://blog.codecentric.de/en/2013/11/traverson/
explorable API / inline documentation
permet aux développeurs de découvrir l’API et structure de données facilement, au lieu de switcher constamment entre code et la doc => meilleure adoption de l’API
Moins besoin de se referer a la doc
simple client logic (no more uri hardcoding)
Le client suit les uri au lieu de les construire
loose coupling between server and client
server can change URIs (including pointing to different domains)
advertise new functionalities
less dependency on URI templates or WADL/WSDL)
URIs sont des implementations, le client n’a pas a les connaitre
Les
http://soabits.blogspot.no/2013/12/selling-benefits-of-hypermedia.html
TODO: lien vers version simplifiee = findtheflow.io#relatedprojects
retour d’experience + pub
business value:
enregistre l’exécution
donnée stocké et comment on les valorise
donnée très hiérarchique et explorable grâce aux HATEOAS
questions a repondre:
inconvenient?
surcout
risque de mal faire
migration impossible surtout cote client, le principe change
impact sur perf? (embedded ressources, caching)
quel niveau pour vous ?
vous avez ca en prod ?
questions a leur poser: