Optimisation du contrôle d’accès GraphQL à grain fin et des performances des requêtes

GraphQL est à la fois un langage de requête pour les API et un runtime pour exécuter ces requêtes avec vos données existantes. Il offre une description complète et claire des données disponibles dans votre API, permet aux clients de demander exactement ce dont ils ont besoin sans excès, facilite l’évolution des API au fil du temps et prend en charge des outils de développement robustes.

Contrôle d’accès GraphQL et Optimisation des requêtes

Contrôle d’accès

L’autorisation est un ensemble de règles ou de logique métier qui détermine si un utilisateur, une session ou un contexte dispose de la liste de contrôle d’accès (ACL) pour effectuer certaines actions ou voir des données spécifiques.

Un tel comportement doit être appliqué au niveau de la couche de logique métier. Bien qu’il puisse être tentant de placer la logique d’autorisation directement dans la couche GraphQL, il est généralement plus approprié de la gérer ailleurs.

Optimisation des requêtes

Optimiser les requêtes GraphQL implique des techniques telles que la minimisation de la récupération et du traitement de données inutiles pour améliorer les temps de réponse et réduire la charge du serveur. Cela résulte en une application plus efficace, offrant une meilleure expérience utilisateur, une meilleure engagement et rétention des utilisateurs, et une scalabilité accrue du serveur.

Voies pour optimiser les requêtes GraphQL

  • N+1 (Chargement groupé)
  • Suremprunt et sous-emprunt
  • Mise en cache pour réduire la latence
  • Pagination

Amélioration du contrôle d’accès GraphQL et de l’optimisation des requêtes GraphQL

Le moteur d’autorisation valide les permissions des nœuds et des champs en utilisant la liste de contrôle d’accès (ACL) et optimise les requêtes GraphQL en fonction des permissions. De plus, le résolveur N+1 améliore les performances en consolidant les requêtes. Cette approche résout le problème N+1. 

Figure 1



Acteurs

  • Requête GraphQL : Une demande envoyée par un client à un serveur GraphQL pour récupérer des données spécifiques.
  • Moteur GraphQL : Fait référence à un service qui permet d’exécuter des requêtes GraphQL.
  • Moteur d’autorisation : Valide les permissions des nœuds et des champs en utilisant ACL et optimise la requête GraphQL en fonction des permissions des champs.
  • Résolveur N+1 : Réduit la surcharge et la latence associées à plusieurs requêtes de base de données, améliorant ainsi les performances et l’efficacité.

Figure 2

Figure 3

Amélioration du contrôle d’accès

Implémentation existante

Supposons qu’une application dispose de Produits, Fournisseurs et Adresses. L’accès aux données des Fournisseurs et des Adresses nécessite une authentification utilisateur, qui peut être facilement gérée dans les résolveurs.

Cependant, les données du fournisseur sont limitées aux utilisateurs administrateurs, et certains champs du fournisseur ne sont accessibles qu’à des rôles spécifiques. Par contre, les produits sont publics et peuvent être consultés avec le rôle Propriétaire du Produit. L’exécution de la requête mentionnée (Figure 3) renverra les données du produit ainsi que les données associées du Fournisseur et de l’Adresse, ce qui pose un problème de sécurité.

Implémentation Améliorée

Les nœuds et les champs de la requête sont validés selon les permissions de l’utilisateur, et une requête GraphQL optimisée est générée.

Figure 3.1 (Flow Diagram)

 

Figure 4

La Figure 4 est un exemple de la manière dont vous pourriez implémenter une authentification personnalisée dans une API GraphQL utilisant Node.js. Dans ce code, le rôle est extrait de l’en-tête d’Authorization et est ensuite utilisé, avec la requête, pour valider l’autorisation.

Figure 5

Dans cet exemple, nous utilisons le rôle et les permissions d’un utilisateur à partir de la session ou de la requête qui contrôlent l’accès à des requêtes et mutations spécifiques dans le schéma GraphQL. Nous avons défini les règles de rôle et de permission dans le schéma GraphQL pour tous les utilisateurs.

Cette méthode vérifie récursivement le rôle et les permissions sur tous les nœuds et champs. Si un nœud ou un champ n’est pas autorisé, alors elle effectue l’une des actions suivantes en fonction de la configuration :

  • Supprimer le nœud ou le champ.
  • Retourner le champ ou le nœud avec un message d’erreur.
  • Lancer une exception.

Une fois que la requête GraphQL est validée par rapport au schéma, cette méthode renverra la requête GraphQL optimisée.

Amélioration de l’Optimisation des Requêtes ORM Utilisant N+1

Implémentation Existante

C’est une question technique qui affecte la performance d’une requête. Elle peut se produire dans des applications qui utilisent un cadre de Mappage Objet-Relationnel (ORM) pour accéder à une base de données.

Elle survient généralement lorsque l’application doit charger une collection d’entités liées depuis la base de données.

Supposons qu’il y ait 2 produits ; il faut faire 1 requête pour récupérer les produits et 2 requêtes supplémentaires pour fetcher les fournisseurs pour chaque produit individuellement.

Figure 6

Figure 7

Une requête récupère la liste des produits, et une requête distincte fetch les fournisseurs pour chaque produit. Le nombre de requêtes de fournisseurs est égal au nombre de produits.

Implémentation Améliorée

Une fois que la demande atteint le résolveur N+1, le résolveur N+1 optimise les requêtes pour minimiser le nombre de demandes à la base de données en les réduisant à une seule requête pour les données principales et une requête supplémentaire pour les données liées, atténuant ainsi efficacement le problème N+1.

  1. Requête de Données Principales : Une seule requête qui récupère l’ensemble principal de données requis pour l’application.
  2. Requête de Données Liées : Une requête supplémentaire fetchant toutes les données liées nécessaires pour compléter le jeu de données.

Figure 8

Figure 9: Total No. of Queries are 2 (1 for Product, 1 for Vendor)

Figure 10

Après que tous les résolveurs de requêtes ont été complétés, le serveur retourne les données optimisées au client au format JSON.

Conclusion

Nous avons souligné que la mise en œuvre de mécanismes d’autorisation fine, ainsi que de mesures de sécurité renforcées, est cruciale pour sécuriser une API GraphQL. Cela inclut à la fois la sécurité au niveau des nœuds et au niveau des champs.

Comme cet article le décrit, le problème N+1 se produit lorsqu’une requête non optimisée entraîne des appels excessifs à la base de données dans GraphQL. Nous avons fourni une solution pour surmonter le problème N+1. Elle diminue l’utilisation des ressources du serveur de base de données, entraînant des économies de coûts et une meilleure scalabilité. De plus, en améliorant les performances des requêtes, cela améliore l’expérience utilisateur en réduisant les temps de réponse des requêtes.

Source:
https://dzone.com/articles/optimizing-fine-grained-graphql-access-control-and-queries