Le node GraphQL dans n8n : requêtes, variables et pagination par curseur
Publié le 23 août 2026 · 7 min de lecture
Shopify a fait de son API GraphQL la référence pour tout nouveau développement, Linear n'expose que ça, GitHub et Monday.com en dépendent pour tout ce qui dépasse leurs opérations les plus courantes — et pourtant, la plupart des guides n8n qui les couvrent traitent GraphQL comme un détail d'implémentation à contourner plutôt que comme un outil à maîtriser. Une étude de Gleison Brito et Marco Tulio Valente, publiée à l'IEEE International Conference on Software Architecture en 2020 (« REST vs GraphQL: A Controlled Experiment », voir sur Google Scholar), mesure ce que ce choix change concrètement : sur les scénarios testés, les clients GraphQL transfèrent nettement moins de données inutiles que leurs équivalents REST, au prix de requêtes plus complexes à écrire correctement. Ce compromis se joue directement dans le node GraphQL de n8n. Ce guide couvre sa configuration, un piège fréquent sur la gestion des erreurs, le paramétrage par variables, et la pagination par curseur — le point qui bloque le plus de monde, faute d'équivalent à l'option Pagination du node HTTP Request.
Le node GraphQL natif de n8n
n8n embarque un node GraphQL dédié, distinct du HTTP Request, avec quatre champs à connaître :
- Endpoint — une seule URL, contrairement à REST où chaque ressource a la sienne ; c'est la requête qui détermine ce qui est renvoyé, pas l'URL.
- Query — le texte de la requête ou de la mutation GraphQL, au format standard.
- Variables — un objet JSON qui alimente les paramètres déclarés dans la requête (voir plus bas).
- Authentication — None, Basic Auth, Header Auth, Query Auth, ou Predefined Credential Type quand n8n propose un credential natif pour le service ciblé (GitHub, Shopify, Linear...), qui évite de reconstruire l'en-tête à la main.
C'est ce même principe de point d'entrée unique que documentent nos guides sur Linear et Monday.com, deux services où l'API GraphQL n'est pas une option avancée mais l'unique porte d'entrée derrière le node dédié.
Le piège du 200 OK qui cache une erreur
C'est la surprise la plus fréquente pour qui découvre GraphQL en venant de REST : une requête malformée, un champ inexistant ou une autorisation refusée ne renvoient presque jamais un statut HTTP d'erreur. Le serveur répond en 200, avec un corps qui contient un champ errors (message, chemin du champ fautif, code éventuel) à côté d'un champ data partiellement ou totalement à null. Le node GraphQL de n8n suit fidèlement cette spécification : tant que la réponse HTTP est un succès, le node ne s'arrête pas en erreur, même si la requête a complètement échoué côté serveur.
La parade est simple mais ne se met jamais en place toute seule : un node IF juste après le node GraphQL, qui teste {{ $json.errors && $json.errors.length > 0 }}. La branche vraie part vers votre logique d'erreur habituelle — voir notre guide de gestion des erreurs avec Error Workflow — plutôt que de laisser un data.utilisateur à null se propager silencieusement dans le reste du workflow et faire planter un node bien plus loin, avec un message d'erreur qui n'aura plus aucun rapport avec la cause réelle.
Variables et requêtes paramétrées
Écrire l'identifiant ou le filtre en dur dans le texte de la requête fonctionne une fois, puis oblige à dupliquer le node pour chaque cas. La bonne pratique GraphQL — déclarer des variables typées dans la requête et les fournir séparément — s'applique telle quelle dans n8n :
query GetIssue($id: String!) {
issue(id: $id) {
title
state { name }
}
}
Le champ Variables du node reçoit alors un objet JSON construit avec une expression n8n classique :
{ "id": "{{ $json.issueId }}" }
Cette séparation entre la forme de la requête (fixe) et ses paramètres (dynamiques) évite l'injection accidentelle de guillemets ou de caractères spéciaux dans le texte de la requête — le même risque, et la même solution, que pour les requêtes paramétrées côté SQL détaillées dans notre guide du node Postgres. Pour la construction de l'objet JSON lui-même à partir de données d'entrée plus complexes, notre guide des expressions et de la syntaxe n8n couvre la manipulation de chaînes et d'objets dans les champs du node.
Node GraphQL natif ou HTTP Request : quand basculer
Le node GraphQL couvre l'essentiel, mais trois situations poussent vers un node HTTP Request classique en POST, avec un corps {"query": "...", "variables": {...}} :
- Un credential prédéfini existe pour le service, mais uniquement côté HTTP Request — cas documenté dans notre guide de connexion de Shopify à n8n, où l'API GraphQL Admin se pilote par HTTP Request avec le même token que le node Shopify natif.
- Des en-têtes très spécifiques que le node GraphQL n'expose pas dans son formulaire.
- Un besoin de contrôle fin sur la pagination et les retries, détaillé juste après — le node HTTP Request s'intègre plus naturellement à une boucle manuelle et à la logique de retry avec backoff.
Dans les deux cas, la requête GraphQL elle-même ne change pas d'une ligne : seul le node qui l'envoie diffère.
Pagination par curseur : le vrai point de friction
L'option Pagination du node HTTP Request (incrémenter un offset, suivre une URL « page suivante ») a été pensée pour REST — voir notre guide complet de la pagination API. Elle ne correspond à rien côté GraphQL, où la quasi-totalité des API (Shopify, GitHub, Linear inclus) utilisent le patron de connexion Relay : chaque requête renvoie un champ pageInfo avec hasNextPage (booléen) et endCursor (un jeton opaque, pas un numéro de page), à réinjecter dans l'appel suivant via une variable after.
Ni la pagination native du HTTP Request ni le node Loop Over Items ne conviennent ici : Loop Over Items boucle sur des données déjà présentes en mémoire, alors que le besoin est de rappeler l'API autant de fois que nécessaire, sans savoir à l'avance combien de pages existent. Le patron qui fonctionne repose sur une boucle construite à la main :
- Un node Set initialise le curseur à
nullpour le premier appel. - Le node GraphQL (ou HTTP Request) exécute la requête avec
after: {{ $json.cursor }}. - Un node IF teste
{{ $json.data.produits.pageInfo.hasNextPage }}: si vrai, la branche reboucle vers l'étape 2 en mettant à jour le curseur avecendCursor; si faux, le flux continue vers l'agrégation des résultats accumulés.
C'est une boucle par rappel de nodes (connexion en arrière dans le canvas), pas un Loop Over Items — le même principe de reprise incrémentale que celui décrit dans notre guide des boucles dans n8n. Pour un import volumineux planifié plutôt qu'à la demande, conserver le dernier curseur traité entre deux exécutions (avec $getWorkflowStaticData ou une table Supabase) évite de tout reparcourir depuis le début à chaque lancement.
Rate limits : à la complexité plutôt qu'au nombre d'appels
Autre différence avec REST : plusieurs API GraphQL (Linear, GitHub) ne limitent pas un nombre brut de requêtes mais un budget de « coût » calculé sur la complexité de chaque requête — nombre de champs, profondeur d'imbrication, taille des listes demandées. Une requête large qui récupère beaucoup de champs imbriqués en un seul appel peut consommer autant de budget que dix requêtes REST simples. Le réflexe reste le même que pour toute API externe : capturer le code d'erreur de dépassement, backoff progressif, et retries bornés — voir notre guide des retries et timeouts avec le node HTTP Request pour la mécanique.
Trois cas concrets où la bascule vaut le coup
- Shopify — le node natif couvre commandes et produits ; passer en GraphQL Admin API évite plusieurs appels REST pour récupérer variantes, metafields et inventaire multi-emplacements en une requête (voir notre guide Shopify).
- GitHub — le node natif couvre issues et pull requests ; les checks, projets et discussions passent par l'API GraphQL, documentée dans notre guide d'automatisation GitHub.
- Linear — l'API est exclusivement GraphQL derrière le node natif ; labels personnalisés, cycles et sous-issues avancées s'écrivent directement en requête, comme détaillé dans notre guide de connexion Linear.
En résumé
Le node GraphQL de n8n couvre la configuration standard — endpoint unique, requête, variables, authentification — mais laisse trois responsabilités à la charge du workflow : vérifier le champ errors malgré un statut 200, construire la pagination par curseur avec une boucle manuelle plutôt qu'une option native, et surveiller des rate limits calculés en complexité plutôt qu'en nombre d'appels. Ces trois réflexes, une fois posés, s'appliquent à l'identique sur Shopify, GitHub, Linear et toute autre API GraphQL que vos workflows viendront interroger.
FAQ
Questions fréquentes
Le node GraphQL natif de n8n suffit-il pour tous les cas ?
Pour la majorité des requêtes et mutations, oui. Il montre ses limites sur trois points précis : l'authentification par credential prédéfini d'un service tiers (Shopify, Linear...), certains en-têtes très spécifiques, et surtout la pagination automatique, absente du node. Dans ces cas, un node HTTP Request en POST avec un corps {query, variables} reproduit exactement le même appel, avec plus de contrôle.
Pourquoi mon node GraphQL ne renvoie-t-il pas d'erreur alors que la requête a échoué ?
Parce que la spécification GraphQL répond quasi systématiquement avec un statut HTTP 200, y compris en cas d'erreur : le détail se trouve dans un champ errors du corps de la réponse, pas dans le code HTTP. Le node GraphQL de n8n ne fait pas automatiquement échouer l'exécution dans ce cas — il faut vérifier soi-même la présence de ce champ avec un node IF juste après.
Comment paginer une API GraphQL dans n8n sans node de pagination dédié ?
L'option Pagination du node HTTP Request (offset, next URL) ne s'applique pas à la pagination par curseur qu'utilisent la plupart des API GraphQL (pattern pageInfo avec hasNextPage et endCursor). La méthode qui fonctionne est une boucle manuelle : un node qui rappelle la requête en réinjectant le curseur reçu à l'itération précédente, jusqu'à ce que hasNextPage passe à false.
Le node GraphQL de n8n peut-il servir d'outil pour un agent IA ?
Oui, exactement comme un node HTTP Request : ajouté en Tool sur un node AI Agent, avec une description claire de ce que la requête retourne, il permet à l'agent d'interroger l'API GraphQL de façon autonome en fonction de la conversation, par exemple pour rechercher un ticket Linear ou un produit Shopify sur demande.
Bundle FlowKit Complet
269 €