backend / graphql
Queries : lire des données
Explication
Ce que vous allez apprendre
- Écrire une query GraphQL simple puis imbriquée sur plusieurs niveaux de relations
- Nommer tes requêtes et comprendre pourquoi c'est indispensable en production
- Utiliser les alias pour requêter le même champ plusieurs fois avec des arguments différents
- Factoriser des sélections de champs répétées avec des fragments
- Sélectionner des champs conditionnellement avec les directives
@includeet@skip
Dans quel contexte ?
Une page de fiche produit d'un site e-commerce doit afficher le nom, le prix, la catégorie et les trois derniers avis clients avec le nom de leur auteur. Un développeur frontend écrit une seule query GraphQL qui décrit cette arborescence exacte, l'envoie au endpoint /graphql, et reçoit une réponse JSON qui a très exactement cette forme — ni plus, ni moins.
D'abord, la forme la plus simple d'une query
Une query anonyme, entre accolades, sélectionne un champ de Query puis les sous-champs voulus sur le type renvoyé. C'est la structure minimale : un champ racine (produit(id: "42")), suivi des champs scalaires qu'on veut lire dessus (nom, prix).
Une fois cette base acquise, il faut prendre l'habitude de nommer ses requêtes
Une query anonyme fonctionne très bien en test rapide, mais en production, chaque requête devrait porter un nom explicite comme ObtenirProduit. Ce nom apparaît dans les logs serveur, dans les outils de monitoring (Apollo Studio, par exemple) et facilite énormément le debug : sans lui, toutes les requêtes ressemblent à "query anonyme" dans les traces.
Ensuite, la sélection peut s'imbriquer sur plusieurs niveaux
Rien n'empêche de descendre plusieurs niveaux de relations dans une même requête : un produit, sa catégorie, les avis de ce produit, et même l'auteur de chaque avis. C'est exactement ce qui règle le problème du sous-fetching vu à la leçon précédente — mais attention, cette imbrication a un coût serveur qui sera abordé dans la leçon sur le problème N+1.
Il reste un cas particulier : et si je veux le même champ deux fois ?
Sans rien de spécial, GraphQL refuserait une ambiguïté si tu demandais deux fois produit avec des arguments différents dans la même sélection. L'alias résout ça : premier: produit(id: "42") renomme la clé du résultat en premier, permettant de comparer plusieurs produits dans une seule requête.
| Concept | Syntaxe | Usage typique |
|---|---|---|
| Query nommée | query ObtenirProduit { ... } | Toujours en production, pour les logs |
| Alias | premier: produit(id: "42") { ... } | Requêter le même champ avec des arguments différents |
| Fragment | fragment X on Produit { ... } | Factoriser une sélection réutilisée plusieurs fois |
| Fragment inline | ... on Produit { ... } | Accéder aux champs spécifiques d'une interface/union |
Maintenant, un problème de duplication apparaît vite
Dès qu'une même sélection de champs (par exemple id, nom, prix, enStock) est répétée dans plusieurs endroits de la requête, la copier-coller devient une source d'erreurs si le besoin change. Les fragments résolvent ce problème : on les déclare une fois avec fragment InfosProduit on Produit { ... }, puis on les réutilise avec ...InfosProduit partout où c'est nécessaire.
Prérequis
Cette leçon suppose que tu connais déjà la structure d'un schéma (types, Query, nullabilité), vue à la leçon précédente : une query ne peut sélectionner que des champs qui existent réellement dans le schéma.
Enfin, la sélection conditionnelle
Les directives standard @include(if: $condition) et @skip(if: $condition) permettent d'inclure ou d'exclure un champ selon une variable booléenne, sans dupliquer toute la requête en deux versions. C'est utile par exemple pour ne charger les avis d'un produit que si l'utilisateur a explicitement déplié cette section de l'interface.
Piège fréquent
Oublier de nommer ses requêtes en production rend le debug d'un endpoint GraphQL très pénible : impossible de savoir, dans les logs ou le monitoring, quelle partie du frontend a déclenché quelle requête. Prends l'habitude de nommer systématiquement, dès le développement.
Une fois à l'aise avec la lecture de données, la suite naturelle est d'apprendre à les modifier : la prochaine leçon aborde les mutations, la façon standard d'écrire des données en GraphQL.
Commandes & code
Queries : lire des données
# Query simple, un seul champ
query {
produit(id: "42") {
nom
prix
}
}
# Query nommée : recommandé en production (debugging, logs, cache client)
query ObtenirProduit {
produit(id: "42") {
nom
prix
}
}
# Sélection imbriquée sur plusieurs niveaux de relations
query ObtenirProduitAvecAvis {
produit(id: "42") {
nom
categorie {
nom
slug
}
avis {
note
commentaire
auteur {
nom
avatar
}
}
}
}
# Alias : renommer un champ dans la réponse, utile pour requêter le même champ deux fois
query ComparerProduits {
premier: produit(id: "42") { nom prix }
second: produit(id: "43") { nom prix }
}
# Fragments : factoriser un ensemble de champs réutilisé plusieurs fois
fragment InfosProduit on Produit {
id
nom
prix
enStock
}
query ListeProduits {
produits(limite: 10) {
...InfosProduit
}
produitsPromotion: produits(limite: 5) {
...InfosProduit
}
}
# Fragments inline sur une interface ou union (voir leçon types complexes)
query DetailsRecherche {
resultat(id: "42") {
... on Produit {
nom
prix
}
... on Categorie {
nom
description
}
}
}
# Directives standard : @include et @skip pour de la sélection conditionnelle
query ObtenirProduit($avecAvis: Boolean!) {
produit(id: "42") {
nom
avis @include(if: $avecAvis) {
note
}
}
}# Introspection : interroger le schéma lui-même (utilisé par les outils comme GraphiQL)
curl -X POST https://api.exemple.com/graphql \
-H "Content-Type: application/json" \
-d '{"query": "{ __schema { types { name } } }"}'Résumé
- Toujours nommer les queries en production : elles apparaissent dans les logs et les outils de monitoring.
- Les fragments (
fragment X on Type) évitent la duplication de sélections de champs répétées. @include(if:)et@skip(if:)permettent une sélection de champs conditionnelle sans dupliquer la requête.- L'introspection (
__schema,__type) permet aux outils de générer de la documentation et de l'autocomplétion.
Exercices pratiques
Mission : optimiser une page fiche produit avec fragments et alias
Objectif : Factoriser une sélection de champs répétée et comparer deux produits dans une seule requête, sans dupliquer le texte de la requête.
Contexte
Le back-office e-commerce affiche une liste de produits standards et une liste de produits en promotion côte à côte, avec exactement les mêmes champs (id, nom, prix, enStock). Le product manager demande aussi un mode "comparateur" qui affiche deux produits précis (id 42 et 43) l'un à côté de l'autre dans un seul écran, chargé par une seule requête réseau.