Module JEE Mettre en place des services Rest

  • Slides: 36
Download presentation
Module JEE Mettre en place des services Rest avec Jax-RS

Module JEE Mettre en place des services Rest avec Jax-RS

REST • REpresentational State Transfert • Architecture Client-Serveur permettant l’échange de ressources à travers

REST • REpresentational State Transfert • Architecture Client-Serveur permettant l’échange de ressources à travers des requêtes et des réponses • Manipulation de ressources § Représentation textuelle (le plus souvent JSON) • Défini en 2000 par Roy Fielding

REST Client Requête HTTP GET https: //restcountries. eu/rest/ v 2/name/france Réponse HTTP 200 Serveur

REST Client Requête HTTP GET https: //restcountries. eu/rest/ v 2/name/france Réponse HTTP 200 Serveur

Caractéristiques REST • Style d’Architecture § Il ne s’agit pas d’une technologie • Echange

Caractéristiques REST • Style d’Architecture § Il ne s’agit pas d’une technologie • Echange Client / Serveur § Faible couplage • Mise en place de CRUD § Create Read Update Delete

API Rest curl -i -H "Accept: application/json" -X GET https: //restcountries. eu/rest/v 2/name/france •

API Rest curl -i -H "Accept: application/json" -X GET https: //restcountries. eu/rest/v 2/name/france • Basé sur un protocole : HTTP • Sur des méthodes : § § § GET POST PUT PATCH DELETE • Type de média § § récupération d’une ou plusieurs ressources création d’une ressource modification d’une ressource mise à jour partielle d’une ressource suppression d’une ressource Application/json Application/xml Atom xhtml

4 Principes d’une API Restful • Toute ressource est associée à un ID §

4 Principes d’une API Restful • Toute ressource est associée à un ID § Give everything an ID / Ressource -> Identifiant • Les ressources sont liées entre elles (HATEOAS) • Utilisation des méthodes HTTP • Plusieurs représentations (JSON, XML…)

Et aussi • Communication sans état ( « stateless » ) § § Pas

Et aussi • Communication sans état ( « stateless » ) § § Pas de conservation de session coté serveur Permet facilement la « scalabilité » horizontale • Utilisation de cache § § Optimisation des vitesses de transfert Amélioration des performances

JAX-RS Java API for RESTful Web. Service

JAX-RS Java API for RESTful Web. Service

JAX-RS 2. 0 • Java API for RESTful Web. Service • Spécification décrivant §

JAX-RS 2. 0 • Java API for RESTful Web. Service • Spécification décrivant § § § Les annotations pour la réalisation d’API REST API pour la réalisation de client Mécanise d’asynchronisme client Serveur Amélioration des mécanismes de négociation Validation Intégration avec JSR 330 (CDI)

Un peu d’histoire • 2008 : JAX-RS 1. 0 § Annotations, • 2009 :

Un peu d’histoire • 2008 : JAX-RS 1. 0 § Annotations, • 2009 : JAX-RS 1. 1 (Java. EE 6) • 2014 : JAX-RS 2. 0 (Java. EE 7) § Client API, Bean Validation, Async • 2017 : JAX-RS 2. 1 (Java. EE 8) § Non Blocking IO, Reactive Client, Server Sent Events (SSE)

Exemple GET http: //localhost: 8080/category/1 GET http: //localhost: 8080/category/? name=test @Path("/category") @Produces(Media. Type. APPLICATION_JSON)

Exemple GET http: //localhost: 8080/category/1 GET http: //localhost: 8080/category/? name=test @Path("/category") @Produces(Media. Type. APPLICATION_JSON) public class Category. Resource { }

Exemple GET http: //localhost: 8080/category/1 GET http: //localhost: 8080/category/? page=1 @Path("/category") @Produces(Media. Type. APPLICATION_JSON)

Exemple GET http: //localhost: 8080/category/1 GET http: //localhost: 8080/category/? page=1 @Path("/category") @Produces(Media. Type. APPLICATION_JSON) public class Category. Resource { @GET @Path("{id}") public Category. DTO find. By. Id(@Path. Param("id") Long id) { … } }

Exemple GET http: //localhost: 8080/category/1 GET http: //localhost: 8080/category/? page=2 @Path("/category") @Produces(Media. Type. APPLICATION_JSON)

Exemple GET http: //localhost: 8080/category/1 GET http: //localhost: 8080/category/? page=2 @Path("/category") @Produces(Media. Type. APPLICATION_JSON) public class Category. Resource { @GET public List<Category. DTO> find. All( @Query. Param("page") @Default. Value("1") int page) { … } }

Des implémentations • Jersey • Resteasy • Restlet • Apache CXF https: //jersey. github.

Des implémentations • Jersey • Resteasy • Restlet • Apache CXF https: //jersey. github. io/ https: //resteasy. github. io/ https: //restlet. com/ https: //cxf. apache. org/

Les annotations

Les annotations

Transcrire les méthodes Http Méthode Objectif Annotation Get Post Récupération d’une ressources Création d’une

Transcrire les méthodes Http Méthode Objectif Annotation Get Post Récupération d’une ressources Création d’une ressource @GET @POST Put Mise à jour d’une ressource @PUT Delete Head Suppression de la ressource Get sans réponse Peut être utiliser pour vérifier l’existence d’une ressource Permet d’obtenir les méthodes supportées @DELETE @HEAD Option @OPTION

Configuration du chemin de base • @Application. Path § Cette annotation permet de définir

Configuration du chemin de base • @Application. Path § Cette annotation permet de définir le chemin de l’application qui servira de base à toutes les urls d’accés aux ressources Toutes les ressources sont préfixées par /api

Déclaration d’une ressource • @Path § § Annotation indiquant que la classe va fournir

Déclaration d’une ressource • @Path § § Annotation indiquant que la classe va fournir des méthodes permettant d’accéder à des ressources Prend en paramètre le chemin de la ressource

Extraire les données Annotation Objectif Exemple @Query. Param Extraction d’un paramètre /? page=1 @Query.

Extraire les données Annotation Objectif Exemple @Query. Param Extraction d’un paramètre /? page=1 @Query. Param("page") long page @Path. Param Extraction d’un élément dans le chemin /category/1 /category/{id} @Path. Param("id") long id @Header. Param Récupération d’un entête http @Header. Param("accept") @Cookie. Param Extraction de la valeur d’un cookie @Cookie. Param("JSESSIONID") @Form. Param Extraction d’un paramétre lors du type de média application/x-www-formurlencoded @Form. Param("name") String name

Extraire les données Annotation Objectif Exemple @Default. Value Assigne une valeur par defaut @Default.

Extraire les données Annotation Objectif Exemple @Default. Value Assigne une valeur par defaut @Default. Value("true") @Query. Param("min-m") boolean has. Min @Context Permet de récupérer des informations sur @Context Http. Headers headers la requête : - Application - Uri. Info - Request - Http. Headers - Security. Context - Provider

Type de contenu • @Consume § Indique le type de contenu consommé par la

Type de contenu • @Consume § Indique le type de contenu consommé par la méthode @POST @Consumes(Media. Type. APPLICATION_JSON) public Response save(Category. DTO category) • @Produce § Indique le type de contenu produit par la méthode @Path("/category") @Produces(Media. Type. APPLICATION_JSON) public class Category. Resource

Classe javax. ws. rs. core. Response • Une méthode Java retournant une ressource peut

Classe javax. ws. rs. core. Response • Une méthode Java retournant une ressource peut directement retourner l’instance de la ressource • Dans le cas où nous souhaitons retourner des informations en plus de la ressources, possibilité d’utiliser la classe « Response » (avec son builder)

Mise en place de cache • Objectifs : § § Réduire la latence Réduire

Mise en place de cache • Objectifs : § § Réduire la latence Réduire la bande passante Eviter les problèmes réseau Réduire les temps de chargement • Solution JAX-RS : Cache. Control

Mise en place de cache @GET @Path("{id}") public Response find. By. Id(@Path. Param("id") Long

Mise en place de cache @GET @Path("{id}") public Response find. By. Id(@Path. Param("id") Long id) { Category. DTO category = this. category. Service. find. By. Id(id) . or. Else. Throw(() -> new Not. Found. Exception("Category not found")); Cache. Control cache. Control = new Cache. Control(); cache. Control. set. Max. Age(120); return Response. ok(category). cache. Control(cache. Control). build(); }

Filtre et intercepteur

Filtre et intercepteur

Filtre / Intercepteur • Filtre § § § Permet d’accéder au message passant par

Filtre / Intercepteur • Filtre § § § Permet d’accéder au message passant par le serveur ou le client. Accède à toutes les données du message (contenu, entêtes, paramètres) Possibilité d’annuler la chaine de traitement • Intercepteur § Permet d’accéder au phase de lecture et d’écriture du message

Filtre / Intercepteur Filtre Intercepteur

Filtre / Intercepteur Filtre Intercepteur

Implémentation Filtre • Implémenter une des interfaces : § § Container. Request. Filter Container.

Implémentation Filtre • Implémenter une des interfaces : § § Container. Request. Filter Container. Response. Filter • Définir la méthode « filter » • Remarque : § Pour annuler le traitement, utiliser la méthode abort. With de la classe Container. Request. Context

Création d’un filtre @Provider @Priority(10) public class Access. Filter implements Container. Request. Filter {

Création d’un filtre @Provider @Priority(10) public class Access. Filter implements Container. Request. Filter { private static final Logger LOGGER = Logger. Factory. get. Logger(Access. Filter. class); @Override public void filter(Container. Request. Context request. Context) throws IOException { LOGGER. info("Acces à l'uri : {}", request. Context. get. Uri. Info(). get. Path()); } } 2019 -05 -14 23: 00: 14, 447 INFO [io. quarkus] (main) Quarkus 0. 14. 0 started in 3. 814 s. Listening on: http: //[: : ]: 8081 2019 -05 -14 23: 00: 14, 447 INFO [io. quarkus] (main) Installed features: [agroal, cdi, hibernate-orm, hibernate-validator, jdbc-h 2, jdbc-mariadb, narayana-jta, resteasy-jsonb, smallrye-openapi, swagger-ui] 2019 -05 -14 23: 00: 48, 556 INFO [fr. nro. int. fil. Access. Filter] (executor-thread-1) Acces à l'uri : /category 2019 -05 -14 23: 00: 56, 960 INFO [fr. nro. int. fil. Access. Filter] (executor-thread-1) Acces à l'uri : /category/1

Filtre avec annulation @Override public void filter(Container. Request. Context request. Context) throws IOException {

Filtre avec annulation @Override public void filter(Container. Request. Context request. Context) throws IOException { LOGGER. info("Acces à l'uri : {}", request. Context. get. Uri. Info(). get. Path()); request. Context. abort. With(Response. status(404). build()); }

Mise en place d’intercepteur • Implémenter les interfaces : § § Reader. Interceptor Writer.

Mise en place d’intercepteur • Implémenter les interfaces : § § Reader. Interceptor Writer. Interceptor • Définir les méthodes associées au interface @Provider public class Build. Interceptor implements Writer. Interceptor { @Override public void around. Write. To(Writer. Interceptor. Context context) { context. get. Headers(). add("running-with", "Quarkus. io"); } }

Mise en place d’un client

Mise en place d’un client

Client Pourquoi intégrer spécifier une spécification pour développer un client ? • Avant Pas

Client Pourquoi intégrer spécifier une spécification pour développer un client ? • Avant Pas de solution dans le JDK. Utilisation de solution trop bas Niveau § Utilisation de URL • Ou utilisation de « commons-httpclient » ou autres librairies • Pas de mécanisme simple pour transmettre et récupérer les données

Depuis JAX-RS 2. 1 • Utilisation des classes « javax. ws. rs. client. Client.

Depuis JAX-RS 2. 1 • Utilisation des classes « javax. ws. rs. client. Client. Builder » et « javax. ws. rs. client. Client » • Facilitant pour : § § § Ajouter des paramètres Poster des flux Récupérer des réponses directement mappées sur des objets

Avant Client OL URL url = new URL("https: //restcountries. eu/rest/v 2/name/france"); URLConnection url. Connection

Avant Client OL URL url = new URL("https: //restcountries. eu/rest/v 2/name/france"); URLConnection url. Connection = url. open. Connection(); url. Connection. set. Do. Input(true); url. Connection. set. Do. Output(false); Buffered. Reader reader = new Buffered. Reader(new Input. Stream. Reader(url. Connection. get. Input. Stream())); String. Builder builder = new String. Builder(); reader. lines(). for. Each(builder: : append); Object. Mapper mapper = new Object. Mapper(); Pays[] pays = mapper. read. Value(builder. to. String(), Pays[]. class); System. out. println(pays[0]); D

Client JAX-RS 2 NE W Client client = Client. Builder. new. Client(); Pays[] pays

Client JAX-RS 2 NE W Client client = Client. Builder. new. Client(); Pays[] pays = client. target("https: //restcountries. eu/rest/v 2/name/france") . query. Param("full. Text", "true") . request() . get(Pays[]. class); System. out. println(pays[0]); NE Response response = client. target("https: //localhost: 8080/api/question") . request() . post(Entity. json(question)); System. out. println(response. get. Status()); W