Les ressources sont identifiées par des URIElles doivent respecter le formalisme suivant :
http://host:port/context/rest/api-name/api-version/path-uri[/...]
exemple : http://sps-int.serv.cdc.fr/clients/1.0/01AGZ201/contrats avec : context : nom de l'application web regroupant les API REST (fichier context.xml) rest : nom associé au dispatcher Spring MVC (fichier web.xml) api-name : nom de la ressource api_version : version de l'API au format M.m resource-uri : chemin(s) associé à la ressource
Utilisation du separator "/" au niveau des URI pour indiquer une relation hiérarchique entre ressources
http://sps-int.serv.cdc.fr/clients/1.0/01AGZ201/contrats
Utilisation possible des caractères "_" et "-" au niveau des URI pour les rendre plus lisibles
http://sps-int.serv.cdc.fr/clients/1.0/recherche-par-nom
Utilisation du caractère "&" pour séparer les paramètres attendu par une ressource
http://sps-int.serv.cdc.fr/clients/1.0?nom=DURAND&limit=30
Eviter l'utilisation du caractère "." qui sert principalemnt à séparer le document de son extension
Le numéro de version doit être intégré aux URI des ressources
Formalisme retenu : http://host:port/context/rest/api-name/M.m/path-uri...
http://sps-int.serv.cdc.fr/clients/1.0/01AGZ201/
Ordre du tri, champ(s) concerné(s)
...?sortByAsc=<champ1>[,<champs2>] ...?sortByDesc=<nom du champ>[,<champs2>] ces deux paramètres peuvent être mixés pour la même requête
Fixe une limite au nombre d'enregistrements retournés
...?limit=<limite> ...?max-results=<limite> http://sps-int.serv.cdc.fr/clients/1.0?sortByAsc=LEPUSU&limit=30
...?after= ...?before= ...?contains= ...?like= ...?match=
si besoin il est possible d'indiquer le champ sur lequel porte la recherche ainsi qu'une limite sur le nombre d'élements à retourner
...?field=<champs> ou ...?<nom du champ>=<valeur> ...?criteria=<champs> ...?limit=<limite> ou ...?max-results=<limite> http://sps-int.serv.cdc.fr/clients/1.0?contains=durand&field=LEPUSU&limit=30
limit | max-results | pageSize : nombre d'éléments retournés (le "pas" de pagination") start | start-index | page : indice du début de la recherche (ne numéro de page)* http://sps-int.serv.cdc.fr/clients/1.0?limit=10&start=3
fonctionelles (recherche avancée, données nécessitant un niveau d'habilitation élevé)
ou technique à des fins d'optimisation et d'amélioration des performances (réduction du nombre de requêtes et taille du payload)
Dans tous les cas, l'API doit permettre au consommateur de préciser unitairement les données qu'il souhaite recueillir ou bien les groupes de données fonctionnellement cohérentes (fragment)
A la demande du consommateur, le payload de la réponse peut inclure des fragments de données complémentaires
Utilisation du mécanisme d'expansion
Consiste à fournir 1,n identifiants de fragment via le paramètre expand
...?expand=<identifiant fragment>[, <identifiant fragment>] //Extraction des contrats et des lignes carrière du client http://sps-int.serv.cdc.fr/clients/1.0/01AGZ201?expand=contrat,carriere
statique (via la documentation de l'API)
dynamique, via un attribut ("expand") positionné au niveau de l'objet parent renvoyé
{ "expand": "contrat, carriere", "self": "http://sps-int.serv.cdc.fr/clients/1.0/01AGZ201", "contrat": { "contrats": [], "size": 3 } "carriere": { "carriere": {}, } }
Il est possible de préciser un sous-fragment d'un fragment via la notation pointée
http://sps-int.serv.cdc.fr/clients/1.0/01AGZ201?expand=contrat.employeur
La liste des champs à renvoyer est indiquer au niveau de la requête via un paramètre
...?fields=<champs1>[,<champ2>]
Anomalie fonctionelle : la validation fonctionnelle (type, taille, pattern, ...etc) des paramètres fournies à échouée
//structure JSON { "typeError":"FieldValidationFault", "message" : "Echec de la validation des données du formulaire", "fieldErrors":[ {"fieldname":"nom","message":"La taille du champ nom doit être comprise entre 3 et 30 caractères","type":"Size"}, {"fieldname":"adresse","message":"La taille du champ adresse doit être comprise entre 5 et 50 caractères","type":"Size"} ] }
L'accès au service REST est sécurisé par un jeton. Ce dernier est absent, mal formé, périmé, ...etc
//structure JSON { "typeError":"UnauthorizedFault", "message" : "unauthorized", }
L'utilisateur ne dispose pas des habilitations suffisantes pour accéder au service
//structure JSON { "typeError":"AccessDeniedFault", "message" : "access denied", }
Erreur technique : L'URI employée est inexistante ou mal formée
Anomalie fonctionelle : La recherche d'une ressource n'aboutie pas
//structure JSON { "typeError": "ResourceNotFoundFault", "message" : "Le librairie recherché est inconnu !", "cause" : "L'identifiant 33 n'existe pas" //Champs facultatif }
Erreur interne grave
//structure JSON { "typeError": "GenericFault", "message" : "Missing header X-RequestID", "stackTrace" : [ {"methodName":"...","fileName":"...","lineNumber":33,"className":"...","nativeMethod":false}, {"methodName":"...","fileName":"...","lineNumber":66,"className":"...","nativeMethod":false}, ... ] }
Deux grands cas d'usage :
Economie bande passante
Economie temps de traitement / CPU
Sécurisation : présentation d'un jeton de sécurité (ACCESS TOKEN)
SLA : possbilité d'appliquer des quotas, plages horaires, abonnements, ...
Traçabilité
Gestion des erreurs
Transformation technique
La gestion des exceptions est centralisée au niveau d'un controlleur spécialisé du Socle DEI
Utilisation de l'annonation @ControllerAdvice(annotations=RestController.class)
HTML is an hypermedia format, allowing link and form controls to let you flow through the application and thereby change the state of the application. This way of using hypermedia of the representation (such as HTML) to denote and manage the state of the application is called hypermedia http://jeremybarthe.com/slides/humantalks-hateoas/#/
self Use this type to link to the preferred URI of the resource. alternate Use this type when providing a link to a URI for an alternative version of the same resource. edit Use this type to link to a URI that clients can use to edit the resource. related Use this type to link to a related resource. previous / next Use these types to link to the previous or next resource in an ordered series of resources. first and last Use these types to link to the first and last
Pageable cf code + conf pour le pageableResolver
date : Yoda time + sérialiser ou simpleDateFormat sur safeJsonObjectMapper + @date sur les DTO
Cette dernière facilite l'ajout de lien(s)
La création d'une ressource à partir de sa réprésentation métier/DTO s'opère par le biais d'un assembler
Exemple ressource Libraire de DESOTE
public class LibraireResource extends AbstractResourceSupport<LibraireDTO> { //private final LibraireDTO libraire; private static final String[] LIBRAIRE_EXPANDS = new String[] { "commandes", "ouvrages" }; public LibraireResource(LibraireDTO libraire, String...expands) { super(libraire, expands); } @Override protected Iterable<String> getDefaultExpand() { return Arrays.asList(LIBRAIRE_EXPANDS); } }
Exemple de représentation JSON générée
{ "content":{"id":6,"nom":"ATTICA la librairie des langues","adresse":"11 Rue Boussingault","codePostal":"75013","ville":"Paris"}, "expand":["ouvrages"], "links":[ {"rel":"self","href":"http://localhost:10080/desote-web-springmvc-spi/web/libraireHATEOAS/6"}, {"rel":"orders","href":"http://localhost:10080/desote-web-springmvc-spi/web/libraireHATEOAS/6/orders"}] }