Conception d’API Java évolutive avec GraphQL

Vous êtes-vous déjà demandé s’il existe un meilleur moyen de récupérer des données pour vos applications que les API REST ? En développement back-end, GraphQL est apparu comme une alternative puissante, offrant une approche plus flexible et efficace pour la récupération de données. Pour les développeurs familiers avec Java, l’intégration de GraphQL dans un back-end moderne ouvre la porte à des API évolutives et performantes adaptées à une large gamme de cas d’utilisation.

Ce blog explorera les principales différences entre GraphQL et REST, mettra en avant les avantages uniques de l’utilisation de GraphQL pour la récupération de données, et vous guidera dans la mise en œuvre d’une API GraphQL en Java avec un exemple concret.

Qu’est-ce que GraphQL ?

GraphQL est un langage de requête pour les API et un moteur d’exécution de ces requêtes. Contrairement à REST, où des points de terminaison fixes renvoient des données prédéfinies, GraphQL permet aux clients de demander exactement les données dont ils ont besoin. Cette granularité rend GraphQL très efficace, notamment pour les applications complexes ou gourmandes en données.

Avantages de l’approche GraphQL :

  • Récupération de données granulaires : Le client peut interroger uniquement le nom et la désignation sans récupérer des champs inutiles comme le département.
  • Requêtes imbriquées : Récupérez les détails du manager ainsi que les informations sur l’employé dans une seule requête.
  • Développement piloté par le schéma : Le schéma agit comme un contrat, facilitant l’évolution de l’API.

Qu’est-ce qu’une API REST ?

Representational State Transfer (REST) est un style architectural pour la construction d’API. Il utilise des méthodes HTTP standard telles que GET, POST, PUT et DELETE pour effectuer des opérations CRUD. REST est connu pour sa simplicité et son adoption généralisée.

Limitations de REST :

  • Surcharge ou sous-charge de données.
  • Exige plusieurs points d’accès et une gestion des versions pour s’adapter aux changements.
  • Aucune capacité intégrée en temps réel.

GraphQL vs. REST API : Quelle est la différence ?

GraphQL et REST sont deux approches populaires pour la construction d’API, chacune avec ses forces. Alors que REST a été la norme pendant des années, GraphQL offre plus de flexibilité et d’efficacité, notamment dans la récupération de données et la collaboration entre les équipes front-end et back-end.

Différences clés

  • Contrairement à REST, qui utilise plusieurs points d’accès et exige une gestion des versions pour les changements, GraphQL consolide la récupération de données dans une seule requête et réduit le besoin de versions car les clients spécifient les exigences en matière de données. 
  • Alors que REST utilise des codes d’état HTTP pour indiquer le succès ou les erreurs, GraphQL renvoie toujours un statut 200 OK et communique les erreurs dans le corps de la réponse. 
  • GraphQL prend également en charge les mises à jour en temps réel via des abonnements, contrairement à REST, qui ne dispose pas de support intégré en temps réel.
  • Bien que REST soit largement établi avec de nombreux outils, l’environnement GraphQL a connu une croissance rapide, offrant des outils puissants comme GraphiQL pour un développement plus facile.
  • Enfin, alors que REST utilise des en-têtes pour le cache, GraphQL nécessite des techniques plus avancées en raison de requêtes dynamiques mais offre des options comme les requêtes persistantes pour un cache efficace.

Concepts fondamentaux de GraphQL

1. Langage de définition de schéma (SDL)

GraphQL a son propre système de types qui est utilisé pour définir le schéma d’une API. La syntaxe pour écrire des schémas s’appelle Langage de définition de schéma (SDL).

2. Requêtes vs. Mutations vs. Abonnements

  • Les requêtes sont utilisées pour récupérer des données du serveur. Contrairement à REST, qui utilise plusieurs points de terminaison fixes, GraphQL utilise un seul point de terminaison, et le client spécifie les données nécessaires dans la requête, offrant ainsi une flexibilité.
  • Les mutations sont utilisées pour modifier des données sur le serveur, comme créer, mettre à jour ou supprimer des données. Elles permettent aux clients d’envoyer des modifications au backend et sont essentielles pour les applications qui ont besoin d’écrire des données.
  • Les abonnements permettent des mises à jour en temps réel en maintenant une connexion stable entre le client et le serveur. Lorsqu’un événement auquel on s’est abonné se produit, le serveur envoie des mises à jour au client, fournissant des flux de données continus, contrairement aux requêtes et aux mutations, qui suivent un cycle de demande-réponse.

3. Schéma GraphQL

Il définit la structure de données qui peut être interrogée ou modifiée, agissant comme un contrat entre le serveur et le client. Il spécifie les types, les champs et les relations disponibles pour que les clients y accèdent. Le schéma comprend généralement des types racines spéciaux : Query pour la récupération de données, Mutation pour la modification de données et Subscription pour les mises à jour en temps réel. Ces types définissent collectivement les capacités de l’API et comment les clients peuvent interagir avec elle.

4. Résolveurs : Mappage des requêtes GraphQL aux données

Les résolveurs sont des fonctions qui gèrent la logique de récupération de données dans un serveur GraphQL. Chaque champ dans un schéma est lié à un résolveur, qui détermine comment récupérer ou calculer les données pour ce champ. Lorsqu’une requête est exécutée, le serveur invoque les résolveurs appropriés pour les champs demandés. Les résolveurs peuvent renvoyer des scalaires ou des objets, l’exécution se poursuivant pour les champs enfants si un objet est renvoyé et se terminant si un scalaire est renvoyé. Si null est renvoyé, l’exécution s’arrête. Les résolveurs sont essentiels pour mapper les requêtes GraphQL aux sources de données réelles.

Avantages de l’utilisation de GraphQL en Java

  1. Récupération exacte des données : Interrogez uniquement les données dont vous avez besoin, rien de plus, garantissant des résultats prévisibles et efficaces.
  2. Requête unique pour plusieurs ressources : Récupérez des données connexes en une seule requête, réduisant les appels API multiples.
  3. Système de types : Organise les APIs par types et champs, garantissant que les requêtes sont valides et que les erreurs sont claires.
  4. Outils pour les développeurs : Améliorez la productivité avec des outils tels que GraphiQL, en utilisant les définitions de types pour une meilleure construction et débogage des requêtes.
  5. Évolution sans version: Ajoutez ou dépréciez des champs sans casser les requêtes existantes, permettant de maintenir les APIs.
  6. Intégration de données flexible: Créez une API unifiée sur des données et du code existants, compatible avec différents moteurs de stockage et langages.

Mise en place d’une API GraphQL en Java

Exemple concret : Utilisateurs et Commandes

Imaginez que vous créez une API d’annuaire d’employés pour une grande organisation. Le but est de permettre aux clients de consulter des détails tels que le nom de l’employé, sa fonction, son service, voire sa hiérarchie de reporting.

1. Configuration du projet

Créez un nouveau projet Spring Boot en utilisant Spring Tool Suite ou en accédant à Spring Initialiser. Ensuite, ajoutez ces dépendances dans le fichier pom.xml:

XML

 

2. Créez vos entités

Créez des entités Java (par ex. Utilisateur et Commande) pour représenter les données qui seront consultées ou modifiées via GraphQL. Par exemple :

Java

 

3. Créez des repositories

Créez des repositories pour interagir avec la base de données:

Java

 

4. Créez des classes de service

Créez des classes de service pour gérer la logique métier:

Java

 

5. Créez des contrôleurs GraphQL

Définissez des contrôleurs GraphQL pour gérer les requêtes et mutations:

Java

 

6. Définissez votre schéma GraphQL

Créez un fichier schema.graphqls dans le répertoire src/main/resources:

Plain Text

 

7. Configurez GraphQL dans application.properties

Configurez éventuellement les paramètres GraphQL dans scr/main/resources/application.properties:

Properties files

 

8. Exécutez votre application

Exécutez l’application SpringBoot en utilisant mvn spring-boot:run ou depuis votre IDE. Une fois en cours d’exécution, vous pouvez accéder au point de terminaison GraphAL à /graphiql.

9. Testez avec des requêtes GraphQL

Testez l’API GraphQL en utilisant un outil comme GraphiQL ou Postman.

Pour la Mutation: 

Plain Text

 

Sortie:

Plain Text

 

Pour la Requête:

Plain Text

 

Sortie:

JSON

 

Fonctionnalités avancées de GraphQL

1. Amélioration de la réutilisabilité avec des fragments

Un fragment est essentiellement un ensemble réutilisable de champs défini pour un type spécifique. C’est une fonctionnalité qui aide à améliorer la structure et la réutilisabilité de votre code GraphQL.

2. Paramétrage des champs avec des arguments

Dans GraphQL, les champs peuvent accepter des arguments pour rendre les requêtes plus dynamiques et flexibles. Ces arguments vous permettent de filtrer ou de personnaliser les données renvoyées par l’API.

3. Pagination et tri avec GraphQL

Pagination

La pagination est un sujet délicat dans la conception d’API. À un niveau élevé, il existe deux approches majeures concernant la façon de l’aborder.

  • Limite-décalage : Demandez un morceau spécifique de la liste en fournissant les indices des éléments à récupérer (en fait, vous fournissez principalement l’indice de départ (décalage) ainsi qu’un nombre d’éléments à récupérer (limite)).
  • Basée sur le curseur : Ce modèle de pagination est un peu plus avancé. Chaque élément de la liste est associé à un ID unique (le curseur). Les clients qui paginent à travers la liste fournissent alors le curseur de l’élément de départ ainsi qu’un nombre d’éléments à récupérer.

Tri

Avec la conception d’API GraphQL, il est possible de renvoyer des listes d’éléments qui sont triées (ordonnées) selon des critères spécifiques.

Défis et considérations de l’utilisation de GraphQL

  • Complexité : Gérer les schémas et les requêtes GraphQL peut être un défi pour des modèles de données simples ou des équipes inexpérimentées.
  • Problèmes de performance : Des requêtes profondément imbriquées peuvent mettre à rude épreuve les ressources backend si elles ne sont pas optimisées.
  • Défis de mise en cache : Les stratégies de mise en cache standard basées sur REST ne s’appliquent pas et nécessitent des solutions personnalisées.
  • Préoccupations de sécurité : Le sur-récupération et les requêtes malveillantes nécessitent des limites de requêtes et d’autres mesures de sécurité.
  • Utilisation hybride : Fonctionne mieux pour des besoins de données complexes, souvent combiné avec REST pour des opérations plus simples.

Conclusion

GraphQL offre une approche flexible et efficace pour construire des API modernes en Java, ce qui en fait un choix idéal pour des applications dynamiques et gourmandes en données. Son architecture à point unique et son typage fort simplifient la conception des API tout en garantissant des performances robustes. Que vous créiez un simple annuaire d’employés ou une plateforme d’analyse complexe, GraphQL permet aux développeurs de fournir des solutions évolutives avec aisance. Commencez à explorer GraphQL aujourd’hui avec des outils comme Spring Boot et graphql-java pour libérer tout son potentiel dans votre prochain projet.

Code source

Vous pouvez trouver le code source complet de ce tutoriel sur Github.

Source:
https://dzone.com/articles/design-scalable-java-apis-with-graphql