Bonnes pratiques GraphQL
GraphQL est suffisamment mature, et est présent depuis assez longtemps, pour que la communauté ait publié de nombreux articles partageant des bonnes pratiques. Ces guides couvrent pratiquement tous les aspects de GraphQL, notamment la conception du schéma, les conventions de nommage, la gestion de la sécurité et la fourniture d'erreurs significatives, entre autres.
Voici quelques-uns des guides les plus convaincants sur les bonnes pratiques en GraphQL.
Bonnes pratiques sur graphql.org
Le site officiel de GraphQL propose une introduction générale aux bonnes pratiques en GraphQL.
Ces points couvrent principalement des préoccupations de haut niveau, telles que :
- Quelle est la meilleure façon de paginer les résultats
- OĂą se situe la couche GraphQL au sein de l'architecture
- Comment utiliser l'interface Node pour l'identification globale des objets
- Comment mettre en cache les résultats
- Et bien d'autres

Les recommandations de Lee Byron
Peu après avoir présenté GraphQL au monde, le créateur de GraphQL Lee Byron a publié l'article Lessons From 4 Years of GraphQL, décrivant comment nous devrions conceptuellement tenter de travailler avec GraphQL :
- Le nommage est important
- Pensez en graphes, pas en endpoints
- Décrivez les données, pas la vue
- GraphQL est une interface légère
- Cachez les détails d'implémentation
Il détaille également plusieurs principes et leçons précieux qu'il a appris en utilisant GraphQL chez Facebook.
GraphQL Rules
GraphQL Rules est un site spécialement dédié à présenter les bonnes pratiques quotidiennes pour travailler avec GraphQL, concernant principalement la conception du schéma GraphQL.
Cette ressource est très complète. Elle compile les informations de quelques ressources exceptionnelles (comme l'article Designing GraphQL Mutations et le tutoriel de Shopify Designing a GraphQL API) et les présente toutes ensemble de manière concise.
Les règles décrites incluent :
- Règles de nommage
- Utilisez
camelCasepour les champs et arguments GraphQL. - Utilisez
UpperCamelCasepour les types GraphQL. - Utilisez
CAPITALIZED_WITH_UNDERSCORESpour nommer les types ENUM.
- Utilisez
- Règles de types
- Utilisez des types scalaires personnalisés si vous souhaitez déclarer des champs ou des arguments avec une valeur sémantique spécifique.
- Utilisez Enum pour les champs qui contiennent un ensemble spécifique de valeurs.
- Règles de champs (Output)
- Utilisez des noms sémantiques pour les champs et évitez de laisser transparaître les détails d'implémentation dans les noms des champs.
- Utilisez le champ
Non-Nullsi le champ aura toujours une valeur donnée. - Regroupez autant de champs liés que possible dans un Object type personnalisé.
- Règles d'arguments (Input)
- Regroupez les arguments couplés dans un nouveau input-type.
- Utilisez des types scalaires stricts pour les arguments, par ex.
DateTimeau lieu deString. - Marquez les arguments comme
requireds'ils sont nécessaires à l'exécution de la requête.
- Règles des listes
- Pour filtrer les listes, utilisez l'argument
filter, qui contient tous les filtres disponibles. - Utilisez l'argument
sortde typeEnumou[Enum!]pour le tri des listes. - Utilisez
limitavec une valeur par défaut etskippour limiter le nombre d'éléments retournés dans la liste. - Utilisez les arguments
page,perPagepour la pagination et retournez un output type avecitems(tableau d'éléments) etpageInfo(méta-données). - Pour les listes infinies (défilement infini), utilisez la Relay Cursor Connections Specification.
- Pour filtrer les listes, utilisez l'argument
- Règles des mutations
- Utilisez les Namespace-types pour regrouper les mutations au sein d'une seule ressource.
- Allez au-delà du CRUD – créez de petites mutations pour différentes opérations métier sur les ressources.
- Envisagez la possibilité d'effectuer des mutations sur plusieurs éléments (modifications par lot du même type).
- Les mutations doivent décrire clairement tous les arguments obligatoires, il ne doit pas y avoir d'options either-either.
- Dans les mutations, placez toutes les variables dans un unique argument input.
- Chaque mutation doit avoir un payload type unique.
Bonnes pratiques pour les resolvers
L'article GraphQL Resolvers: Best Practices décrit comment créer au mieux les resolvers de champs. Bien qu'il soit destiné aux serveurs Node.js (l'infrastructure de PayPal est basée sur Express), plusieurs de ses leçons peuvent également s'appliquer à d'autres technologies, y compris PHP.
Les principaux enseignements sont :
- La récupération et le passage de données de parent à enfant doit être utilisé avec modération.
- Utilisez des bibliothèques comme dataloader pour dédupliquer les requêtes descendantes.
- Soyez conscient de la pression que vous exercez sur vos sources de données.
- Ne mutez pas « context ». Garantit un code cohérent et moins sujet aux bugs.
- Écrivez des resolvers lisibles, maintenables et testables. Pas trop complexes.
- Rendez vos resolvers aussi légers que possible. Extrayez la logique de récupération de données vers des fonctions async réutilisables.
OWASP - GraphQL Cheat Sheet
L'OWASP (Open Web Application Security Project) est une fondation à but non lucratif qui œuvre pour améliorer la sécurité des logiciels. Elle mène des recherches sur la manière dont différentes technologies sont vulnérables aux exploits, et décrit en détail des solutions aux problèmes de sécurité, facilitant ainsi la prévention des attaques pour les développeurs.
L'OWASP a publié la GraphQL Cheat Sheet, expliquant quelles sont les attaques les plus courantes et les plus grands problèmes de sécurité dans GraphQL, et comment les traiter.
Les attaques courantes contre GraphQL sont :
- Injection - cela inclut généralement mais ne se limite pas à :
- Injection SQL et NoSQL
- Injection de commandes OS
- Injection SSRF et CRLF / Request Smuggling
- DoS (Denial of Service)
- Abus d'autorisation défaillante : accès impropre ou excessif, incluant IDOR
- Batching Attacks, une méthode d'attaque par force brute spécifique à GraphQL
- Abus de configurations par défaut non sécurisées
L'OWASP fournit ensuite des recommandations sur la façon d'éviter chacune de ces situations.
Bonnes pratiques avec les requĂŞtes GraphQL
L'équipe Apollo a publié les GraphQL query best practices, donnant des perspectives pratiques sur les façons concrètes de composer la requête GraphQL.
Par exemple, ces deux requêtes atteignent le même objectif, mais parce que la première a un nom d'opération, elle est plus compréhensible et utile lors du débogage :
# Recommandé ✅
query GetBooks {
books {
title
}
}
# Non recommandé ❌
query {
books {
title
}
}Leurs suggestions incluent :
- Nommer toutes les opérations
- Utiliser des variables pour fournir les arguments GraphQL
- Interroger uniquement les données dont vous avez besoin, là où vous en avez besoin
- Utiliser des fragments pour encapsuler des ensembles de champs liés
- Interroger les données globales et les données spécifiques à l'utilisateur séparément
Tirer parti du one graph
Également de l'équipe Apollo, le site Principled GraphQL explique que GraphQL n'est pas seulement une spécification mais, peut-être plus important encore, une interface pour interagir avec le « graphe » de données de notre entreprise.
À travers une liste de 10 principes, ce site décrit comment tirer le meilleur parti du graphe unique :
- One Graph : votre entreprise doit disposer d'un graphe unifié, plutôt que de multiples graphes créés par chaque équipe.
- Federated Implementation : bien qu'il n'y ait qu'un seul graphe, l'implémentation de ce graphe doit être fédérée entre plusieurs équipes.
- Track the Schema in a Registry : il doit y avoir une source unique de vérité pour enregistrer et suivre le graphe.
- Abstract, Demand-Oriented Schema : le schéma doit agir comme une couche d'abstraction qui offre de la flexibilité aux consommateurs tout en cachant les détails d'implémentation du service.
- Use an Agile Approach to Schema Development : le schéma doit être construit de manière incrémentale sur la base d'exigences réelles et évoluer progressivement au fil du temps.
- Iteratively Improve Performance : la gestion des performances doit être un processus continu, basé sur les données, s'adaptant progressivement aux charges de requêtes et aux implémentations de services changeantes.
- Use Graph Metadata to Empower Developers : les développeurs doivent être équipés d'une connaissance approfondie du graphe tout au long du processus de développement.
- Access and Demand Control : accordez l'accès au graphe par client, et gérez ce que les clients peuvent accéder et comment.
- Structured Logging : capturez des logs structurés de toutes les opérations du graphe et utilisez-les comme outil principal pour comprendre l'utilisation du graphe.
- Separate the GraphQL Layer from the Service Layer : adoptez une architecture en couches avec la fonctionnalité du graphe divisée en une couche séparée plutôt qu'intégrée dans chaque service.