Blog ENI : Toute la veille numérique !
🐠 -25€ dès 75€ 
+ 7 jours d'accès à la Bibliothèque Numérique ENI. Cliquez ici
Accès illimité 24h/24 à tous nos livres & vidéos ! 
Découvrez la Bibliothèque Numérique ENI. Cliquez ici
  1. Livres et vidéos
  2. Java Spring
  3. Utilisation de GraphQL
Extrait - Java Spring Le socle technique des applications Jakarta EE (4e édition)
Extraits du livre
Java Spring Le socle technique des applications Jakarta EE (4e édition) Revenir à la page d'achat du livre

Utilisation de GraphQL

Introduction

GraphQL est une alternative aux API REST. Il est constitué d’un langage de requête et d’un environnement d’exécution. Il a été créé par Facebook en 2012, puis a été mis en open source en 2015.

Pour rappel, voici les évolutions des façons d’appeler un traitement distant :

Année

Protocole

Explication

1980

RPC

Remote Procedure Call : appel système externe avec IDL (Interface Definition Language).

1998

XML-RPC

Utilisation de XML pour les échanges.

2005

JSON-RPC

Utilisation de JSON pour les échanges.

1998→2009

SOAP (successeur de XML-RPC)

Utilisation de XML pour les échanges avec un IDL : WSDL.

2000

REST avec  Verbes HTTP

Le serveur choisit la représentation des données dans la réponse, REST sans IDL : Swagger puis OpenAPI.

2007

FQL

Facebook Query Language : GET /fql?q=<requête SELECT...>.

2008

YQL

Yahoo Query Language : GET /fql?q=<requête SELECT… avec jointures>, API de composition.

2012

GraphQL

Suit le protocole RPC en plus universel : avec fetch/mutation/subscription.

GraphQL s’appuie sur des requêtes POST qui sont donc à mettre en cache du côté du client. Ces requêtes indiquent l’ordre et la sélection des champs à remonter du serveur. Le serveur définit le contrat d’échange...

Le schéma

Avant de voir les requêtes, nous devons étudier le schéma de GraphQL, qui a un format spécifique, sur lequel s’appuient les requêtes.

Le schéma permet de lister les données que les clients demandent via des types d’objets. Le développeur de l’API fait l’association entre chaque champ d’un schéma avec une fonction nommée resolver qui produit une valeur lors de l’exécution.

Le schéma se décompose en sections qui sont identifiées par leur type. Il y a les types propres aux opérations et ceux relatifs à la description des données.

Un schéma est un graphe qui est généralement conçu et décrit en quatre étapes :

  • Type Object

  • Type Scalar

  • Type Query

  • Type Mutation

Commençons par des nœuds de graphes qui représentent les données :

type Livre {  
}  
  
type Auteur {  
} 

Ajoutons ensuite les types scalaires (Scalar) en utilisant les types intégrés Int, Float, String, Boolean, and ID. Au niveau du type, nous pouvons indiquer que la variable est optionnelle via l’utilisation du « ! ».

type Livre {  
 titre: String!  
 Contenu: String!  
}  
  
type Auteur {  
 nom: String!  
} 

Ajoutons ensuite...

Intégration de GraphQL dans Spring

Initialement, nous avions le projet GraphQL Java Spring créé par les équipes de GraphQL : https://github.com/graphql-java/graphql-java-spring. Ce projet a évolué pour être intégré dans Spring sous le nom de Spring for GraphQL et sert maintenant de projet de base pour tout nouveau projet. La récente intégration directe de GraphQL dans Spring n’est pas encore GA (General Availability). Au moment de la rédaction de cet ouvrage, la version était toujours en 1.0.0-M6 PRE. Son avantage est de simplifier l’exposition de l’API à travers une adaptation des contrôleurs REST classiques Spring.

Les exemples Spring peuvent être trouvés ici : https://github.com/spring-projects/spring-graphql/tree/main/samples

GraphQL demande au minimum :

  • JDK8

  • Spring Framework 5.3

  • GraphQL Java 17

  • Spring Data 2021.1.0 ou plus pour le QueryDSL et le Query par l’Exemple

La couche de transport peut utiliser HTTP et les WebSockets. De même, nous pouvons utiliser Spring MVC ou Spring WebFlux.

Nous pouvons utiliser l’extension Spring Data Querydsl avec GraphQL.

L’extension Spring Data Querydsl

Querydsl est une bibliothèque qui permet de simplifier la création des prédicats de requête en générant un méta-modèle à l’aide d’un préprocesseur d’annotations. La bibliothèque est indépendante de Spring et elle est disponible ici : http://querydsl.com/.

Voici un exemple simple pour illustrer son utilisation :

List<Person> persons = queryFactory.selectFrom(person)  
 .where(  
   person.firstName.eq("John"),  
   person.lastName.eq("Doe"))  
 .fetch(); 

Son utilisation avec GraphQL et Spring simplifie le code. Nous créons un Bean Repository de type QuerydslPredicateExecutor qui manipule des DataFetcher. Spring Data couvre JPA, MongoDB et LDAP pour l’utilisation QuerydslPredicateExecutor.

Par exemple :

Pour un résultat unique :

// For single result queries  
DataFetcher<Account> dataFetcher =  
       QuerydslDataFetcher.builder(repository).single(); 

Pour un résultat sous forme de liste :

// For multi-result queries  
DataFetcher<Iterable<Account>> dataFetcher =  
       QuerydslDataFetcher.builder(repository).many(); 

Le DataFetcher construit un Querydsl Predicate à partir des paramètres...

Les contrôleurs GraphQL

Les contrôleurs GraphQL sont des contrôleurs classiques REST qui sont personnalisés. Ces contrôleurs sont détectés par l’AnnotatedControllerConfigurer. Nous indiquons qu’une méthode du contrôleur correspond à un champ de requête via l’utilisation de l’annotation @QueryMapping. La requête est déterminée à partir du nom de la méthode si celle-ci n’est pas spécifiée en paramètre de l’annotation.

@Controller  
public class BonjourController {  
  
       @QueryMapping   
       public String bonjour() {   
           return "Bonjour à vous!";  
       }  
} 

Le RuntimeWiring.Builder est utilisé pour enregistrer en tant que graphql.schema.DataFetcher la requête nommée "bonjour".

@SchemaMapping

Il est possible de personnaliser le nom du type parent et le nom du champ dans l’annotation @SchemaMapping :

@Controller  
public class LivreController {  
  
   @SchemaMapping(typeName="Livre", field="auteur ")  
   public Auteur getAuteur(Livre livre) {  
   ...

Autoconfiguration

Nous ne détaillons que la version HTTP pour illustration. Un exemple complémentaire basé sur WebFlux est disponible dans les exemples téléchargeables. La configuration automatique se fait via le GraphQlWebMvcAutoConfiguration. Il y a un équivalent pour WebFlux : le GraphQlWebFluxAutoConfiguration.

1. Version HTTP

Comme les applications RESTful web services, les services GraphQL sont basés sur un Contrôleur REST qui appelle un Service qui appelle un DAO ou un Repository, ce qui permet d’accéder aux données d’une base. Des Beans Spring spécialisés permettent de simplifier le code.

Le handler GraphQlHttpHandler gère les requêtes GraphQL pour les requêtes HTTP via les intercepteurs de requêtes web. Les requêtes web passent par le verbe POST avec le détail demandé spécifié dans le body avec un format JSON répondant à la spécification GraphQL par HTTP.

Il y a deux niveaux de contrôle. Le premier niveau vérifie que la requête HTTP est bien formée et que le body JSON est décodable. En cas de succès, nous avons le statut de la réponse HTTP à OK (200). Le second niveau est positionné par le requêteur GraphQL qui positionne les éventuelles erreurs dans le champ « errors » de la réponse. Un bean...

Conclusion

GraphQL permet de créer une API qui permet de gérer plus finement les requêtes à travers un service de discovery qui indique ce qu’il est possible de faire par l’API. Nous aurons sûrement à l’avenir des serveurs GraphQL réactifs couplés à du Server Site Event qui permettront de répondre à un large éventail de besoins.

Cependant, comme toute « technologie émergente », il faudra un peu de temps pour voir si son adoption sera large ou pas.

Points clés

  • GraphQL évite d’avoir en retour des données au contenu insuffisant : under-fetching.

  • GraphQL évite d’avoir en retour des données au contenu surnuméraire : over-fetching.

  • Spring facilite l’utilisation de GraphQL.

  • GraphQL permet de gérer un abonnement à un flux de données.

  • GraphQL est facile à coupler avec JPA via l’utilisation de Spring Data Querydsl. 

  • GraphQL permet d’aller plus loin que les serveurs RESTful classiques.