Retour au cours

backend / graphql

Arguments et variables

Leçon 61 exercice

Explication

Ce que vous allez apprendre

  • Ajouter des arguments à n'importe quel champ du schéma, pas seulement à Query/Mutation
  • Déclarer des variables typées, avec ou sans valeur par défaut, dans une requête
  • Comprendre la différence entre une valeur par défaut sur une variable et sur un argument de schéma
  • Utiliser un type enum comme argument pour restreindre les valeurs possibles
  • Voir comment les arguments deviennent des paramètres de fonction côté serveur

Dans quel contexte ?

Une page produit affiche ses avis clients, mais uniquement les 3 mieux notés (note supérieure ou égale à 4). Le frontend a besoin de paramétrer cette sélection directement dans la requête GraphQL, sans créer un champ différent pour chaque combinaison de filtres possible. C'est exactement le rôle des arguments de champ.

D'abord, un rappel important : les arguments ne sont pas réservés à la racine

Contrairement à une intuition fréquente chez les débutants, n'importe quel champ du schéma peut recevoir des arguments, pas seulement Query et Mutation. Le champ avis sur le type Produit peut très bien accepter limite et noteMinimum, exactement comme produits sur Query accepte limite.

Une fois ce principe posé, il faut distinguer deux façons de fixer une valeur par défaut

Une valeur par défaut peut être définie à deux endroits différents, et ce n'est pas la même chose : sur la déclaration de la variable dans la requête ($prixMax: Float = 1000.0), ou directement sur l'argument dans le schéma (limite: Int = 20). La première s'applique si le client omet la variable dans ses variables envoyées ; la seconde s'applique si le client omet carrément l'argument dans le texte de sa requête.

Endroit de la valeur par défautS'applique quandExemple
Sur la variable ($x: Int = 20)Le client ne fournit pas x dans variablesRequête générique réutilisable côté client
Sur l'argument de schéma (champ(x: Int = 20))Le client omet complètement l'argumentUne valeur par défaut garantie côté serveur

Ensuite, comment restreindre les valeurs possibles d'un argument ?

Un argument de type String accepterait n'importe quel texte, ce qui n'est pas souhaitable pour un tri ("prix_croissant", "n_importe_quoi"). Un enum, comme OrdreTri, liste un ensemble fermé de valeurs valides ; le serveur rejette automatiquement toute valeur en dehors de cet ensemble, avant même d'exécuter le resolver.

Prérequis

Cette leçon suppose que tu es à l'aise avec l'écriture d'une query avec variables (leçon 3) et que tu comprends la structure d'un resolver (leçon 5) : les arguments finissent toujours en paramètres de la fonction resolver.

Il reste une question de sécurité et de performance à garder en tête

Toujours valider et typer les arguments côté schéma plutôt que de les recevoir en texte libre. Un argument limite: Int mal borné pourrait permettre à un client de demander limite: 1000000, ce qui ramène en mémoire un volume de données disproportionné — un sujet approfondi dans la leçon sur la sécurité et la limitation de complexité.

Bonne pratique

Utilise systématiquement des variables plutôt que des valeurs écrites en dur dans le texte de la requête, même pour un simple limite: 10. Cela permet à un client comme Apollo Client de mettre en cache le texte de la requête indépendamment des valeurs, et de réutiliser la même requête nommée pour différents besoins.

Une fois les arguments et variables maîtrisés, la prochaine leçon aborde des constructions de type plus riches — interfaces, unions et enums — qui permettent de modéliser des situations où plusieurs types différents doivent cohabiter dans une même réponse.

Commandes & code

Arguments et variables

graphql
# Arguments sur n'importe quel champ, pas seulement sur Query/Mutation racine
type Produit {
  id: ID!
  nom: String!
  # Un champ peut avoir ses propres arguments : ici, limiter/filtrer les avis
  avis(limite: Int = 5, noteMinimum: Int): [Avis!]!
}

query {
  produit(id: "42") {
    nom
    avis(limite: 3, noteMinimum: 4) {
      note
      commentaire
    }
  }
}
graphql
# Variables typées avec valeur par défaut, obligatoires ou optionnelles
query RechercherProduits(
  $terme: String!
  $categorieId: ID
  $prixMax: Float = 1000.0
  $trier: OrdreTri = PRIX_CROISSANT
) {
  rechercheProduits(
    terme: $terme
    categorieId: $categorieId
    prixMax: $prixMax
    ordre: $trier
  ) {
    nom
    prix
  }
}
json
// Variables envoyées avec la requête HTTP
{
  "query": "query RechercherProduits($terme: String!, $prixMax: Float) { ... }",
  "variables": {
    "terme": "clavier",
    "prixMax": 150.0
  }
}
graphql
# Enum utilisé comme type d'argument (voir leçon types complexes pour la déclaration complète)
enum OrdreTri {
  PRIX_CROISSANT
  PRIX_DECROISSANT
  PLUS_RECENT
}

# Arguments par défaut au niveau du schéma lui-même (pas seulement des variables)
type Query {
  produits(limite: Int = 20, decalage: Int = 0): [Produit!]!
}
python
# Côté serveur (Strawberry) : les arguments deviennent des paramètres de fonction typés
import strawberry
from enum import Enum

@strawberry.enum
class OrdreTri(Enum):
    PRIX_CROISSANT = "prix_croissant"
    PRIX_DECROISSANT = "prix_decroissant"

@strawberry.type
class Query:
    @strawberry.field
    def produits(self, limite: int = 20, decalage: int = 0, ordre: OrdreTri = OrdreTri.PRIX_CROISSANT) -> list[Produit]:
        return base_de_donnees.lister_produits(limite=limite, decalage=decalage, ordre=ordre.value)

Résumé

  • N'importe quel champ (pas seulement Query/Mutation) peut recevoir des arguments, y compris avec valeurs par défaut.
  • Les variables sont typées et validées par le serveur avant l'exécution du resolver — jamais d'interpolation manuelle.
  • Une valeur par défaut peut être définie à deux niveaux : sur la variable de la requête ou sur l'argument du schéma.
  • Toujours préférer les variables aux valeurs en dur pour permettre la mise en cache des requêtes côté client.

Exercices pratiques

1 disponible
1

Mission : paramétrer une liste d'avis triés sans casser le cache client

Objectif : Ajouter des arguments à un champ non-racine et un enum de tri, en distinguant les deux niveaux possibles de valeur par défaut.

Contexte

Un développeur junior de l'équipe pense que seuls les champs de Query peuvent recevoir des arguments. Il vient de bloquer sur le champ avis du type Produit, qui doit pourtant accepter limite et noteMinimum pour n'afficher que les avis les mieux notés, exactement comme produits(limite: 20) le fait déjà à la racine.

Résoudre l’exercice →