Querying > API GraphQL

API GraphQL

Reading time: 11 min

This guide explains the GraphQL Query API that is used for The Graph Protocol.

Requêtes

Lien vers cette section

Dans votre schéma de subgraph, vous définissez des types appelés Entités. Pour chaque type Entity, un champ entity et entities sera généré sur le type Query de niveau supérieur. Notez que query n'a pas besoin d'être inclus en haut de la requête graphql lors de l'utilisation de The Graph.

Requête pour une seule entité Token définie dans votre schéma :

{
token(id: "1") {
id
owner
}
}

Remarque : Lors d'une requête pour une seule entité, le champ id est obligatoire et il doit s'agir d'une chaîne.

Interrogez toutes les entités Token :

{
tokens {
id
owner
}
}

Lors de l'interrogation d'une collection, le paramètre orderBy peut être utilisé pour trier selon un attribut spécifique. De plus, orderDirection peut être utilisé pour spécifier le sens du tri, asc pour ascendant ou desc pour décroissant.

{
tokens(orderBy : price, orderDirection : asc) {
id
propriétaire
}
}

Exemple de tri d'entités imbriquées

Lien vers cette section

Depuis Graph Node v0.30.0, les entités peuvent être triées sur la base d'entités imbriquées.

Dans l'exemple suivant, nous trions les jetons en fonction de leur nom propre:

{
jetons (orderBy : propriétaire__nom, orderDirection : asc) {
identifiant
propriétaire {
{
name
}
}
}
}

Actuellement, vous pouvez trier par types String ou ID profonds à un niveau sur les champs @entity et @derivedFrom. Malheureusement, le tri par interfaces sur des entités d'un seul niveau, le tri par champs qui sont des tableaux et des entités imbriquées est pas encore pris en charge.

Lors de l'interrogation d'une collection, le paramètre first peut être utilisé pour paginer depuis le début de la collection. Il convient de noter que l'ordre de tri par défaut est par ID dans l'ordre alphanumérique croissant, et non par heure de création.

De plus, le paramètre skip peut être utilisé pour ignorer des entités et paginer. par exemple. first:100 affiche les 100 premières entités et first:100, skip:100 affiche les 100 entités suivantes.

Les requêtes doivent éviter d'utiliser de très grandes valeurs de skip car elles fonctionnent généralement mal. Pour récupérer un grand nombre d'éléments, il est préférable de parcourir les entités sur la base d'un attribut, comme le montre le dernier exemple.

Exemple utilisant first

Lien vers cette section

Interroger les 10 premiers tokens :

{
tokens(first: 10) {
id
owner
}
}

Pour rechercher des groupes d'entités au milieu d'une collection, le paramètre skip peut être utilisé conjointement avec le paramètre first pour ignorer un nombre spécifié d'entités en commençant par le début. de la collection.

Exemple utilisant first et skip

Lien vers cette section

Interrogez 10 entités Token, décalées de 10 places depuis le début de la collection :

{
tokens(first: 10, skip: 10) {
id
owner
}
}

Exemple utilisant first et id_ge

Lien vers cette section

Si un client a besoin de récupérer un grand nombre d'entités, il est beaucoup plus performant de baser les requêtes sur un attribut et de filtrer par cet attribut. Par exemple, un client récupérerait un grand nombre de jetons en utilisant cette requête :

query manyTokens($lastID: String) {
tokens(first: 1000, where: { id_gt: $lastID }) {
id
owner
}
}

La première fois, il enverrait la requête avec lastID = "", et pour les requêtes suivantes, il définirait lastID sur l'attribut id du dernier entité dans la demande précédente. Cette approche fonctionnera nettement mieux que l'utilisation de valeurs skip croissantes.

Vous pouvez utiliser le paramètre where dans vos requêtes pour filtrer différentes propriétés. Vous pouvez filtrer sur plusieurs valeurs dans le paramètre where.

Exemple utilisant where

Lien vers cette section

Afficher les défis (Challenges) avec résultat failed (échec) :

{
challenges(where: { outcome: "failed" }) {
challenger
outcome
application {
id
}
}
}

Vous pouvez utiliser des suffixes comme _gt, _lte pour comparer les valeurs :

Exemple de filtrage de plage

Lien vers cette section
{
applications(where: { deposit_gt: "10000000000" }) {
id
whitelisted
deposit
}
}

Exemple de filtrage par bloc

Lien vers cette section

Vous pouvez également filtrer les entités par _change_block(number_gte: Int) - cela filtre les entités qui ont été mises à jour dans ou après le bloc spécifié.

Cela peut être utile si vous cherchez à récupérer uniquement les entités qui ont changé, par exemple depuis la dernière fois que vous avez interrogé. Ou bien, il peut être utile d'étudier ou de déboguer la façon dont les entités changent dans votre subgraph (si combiné avec un filtre de bloc, vous pouvez isoler uniquement les entités qui ont changé dans un bloc spécifique).

{
applications(where: { _change_block: { number_gte: 100 } }) {
id
whitelisted
deposit
}
}

Exemple de filtrage d'entités imbriquées

Lien vers cette section

Un filtrage sur la base d'entités imbriquées est possible dans les champs portant le suffixe _.

Cela peut être utile si vous souhaitez récupérer uniquement les entités dont les entités au niveau enfant remplissent les conditions fournies.

{
challenges(where: { application_: { id: 1 } }) {
challenger
outcome
application {
id
}
}
}

Opérateurs logiques

Lien vers cette section

Depuis Graph Node v0.30.0, vous pouvez regrouper plusieurs paramètres dans le même argument where en utilisant les opérateurs et ou ou pour filtrer les résultats en fonction de plusieurs critères.

Opérateur AND
Lien vers cette section

Dans l'exemple suivant, nous filtrons les défis (Challenges) dont le résultat et le numéro number supérieur ou égal à 100.

{
challenges(where: { and: [{ number_gte: 100 }, { outcome: "succeeded" }] }) {
challenger
outcome
application {
id
}
}
}

Sucre syntaxique : Vous pouvez simplifier la requête ci-dessus en supprimant l'opérateur et en passant une sous-expression séparée par des virgules.

{
challenges(where: { number_gte: 100, outcome: "succeeded" }) {
challenger
outcome
application {
id
}
}
}
Opérateur OR
Lien vers cette section

Dans l'exemple suivant, nous filtrons les défis dont le résultat réussi (outcome succeeded) ou le numéro (number) est supérieur ou égal à 100.

{
challenges(where: { or: [{ number_gte: 100 }, { outcome: "succeeded" }] }) {
challenger
outcome
application {
id
}
}
}

Remarque : lors de la création de requêtes, il est important de prendre en compte l'impact sur les performances de l'utilisation de l'opérateur ou. Bien que ou puisse être un outil utile pour élargir les résultats de recherche, il peut également avoir des coûts importants. L'un des principaux problèmes avec ou est qu'il peut ralentir les requêtes. En effet, ou nécessite que la base de données parcoure plusieurs index, ce qui peut prendre du temps. Pour éviter ces problèmes, il est recommandé aux développeurs d'utiliser les opérateurs et à la place de ou chaque fois que cela est possible. Cela permet un filtrage plus précis et peut conduire à des requêtes plus rapides et plus précises.

Tous les filtres

Lien vers cette section

Liste complète des suffixes de paramètres :

_
_not
_gt
_lt
_gte
_lte
_in
_not_in
_contains
_contains_nocase
_not_contains
_not_contains_nocase
_starts_with
_starts_with_nocase
_ends_with
_ends_with_nocase
_not_starts_with
_not_starts_with_nocase
_not_ends_with
_not_ends_with_nocase

Veuillez noter que certains suffixes ne sont pris en charge que pour des types spécifiques. Par exemple, Boolean ne prend en charge que _not, _in et _not_in, mais _ est disponible uniquement pour les types d’objet et d’interface.

En outre, les filtres globaux suivants sont disponibles dans le cadre de l'argument where :

_change_block(numéro_gte : Int)

Interrogation des états précédents

Lien vers cette section

Vous pouvez interroger l'état de vos entités non seulement pour le dernier bloc, qui est la valeur par défaut, mais également pour un bloc arbitraire du passé. Le bloc dans lequel une requête doit se produire peut être spécifié soit par son numéro de bloc, soit par son hachage de bloc en incluant un argument block dans les champs de niveau supérieur des requêtes.

Le résultat d'une telle requête ne changera pas au fil du temps, c'est-à-dire qu'une requête portant sur un certain bloc passé renverra le même résultat quel que soit le moment où elle est exécutée, à l'exception d'une requête portant sur un bloc très proche de la tête de la chaîne, dont le résultat pourrait changer s'il s'avérait que ce bloc ne se trouvait pas sur la chaîne principale et que la chaîne était réorganisée. Une fois qu'un bloc peut être considéré comme définitif, le résultat de la requête ne changera pas.

Il convient de noter que l'implémentation actuelle est encore sujette à certaines limitations qui pourraient violer ces garanties. L'implémentation ne peut pas toujours dire qu'un bloc donné n'est pas du tout sur la chaîne principale, ou que le résultat d'une requête par bloc de hachage pour un bloc qui ne peut pas encore être considéré comme final peut être influencé par une réorganisation du bloc qui se déroule en même temps que la requête. Ils n'affectent pas les résultats des requêtes par hachage de bloc lorsque le bloc est final et que l'on sait qu'il se trouve sur la chaîne principale. Ce numéro explique ces limitations en détail.

{
challenges(block: { number: 8000000 }) {
challenger
outcome
application {
id
}
}
}

Cette requête renverra les entités Challenge et les entités Application qui leur sont associées, telles qu'elles existaient directement après le traitement du bloc numéro 8 000 000.

{
challenges(block: { hash: "0x5a0b54d5dc17e0aadc383d2db43b0a0d3e029c4c" }) {
challenger
outcome
application {
id
}
}
}

Cette requête renverra les entités Challenge et leurs entités Application associées, telles qu'elles existaient directement après le traitement du bloc avec le hachage donné.

Requêtes de recherche en texte intégral

Lien vers cette section

Les champs de requête de recherche en texte intégral fournissent une API de recherche textuelle expressive qui peut être ajoutée au schéma du subgraph et personnalisée. Reportez-vous à Définition des champs de recherche en texte intégral pour ajouter la recherche en texte intégral à votre subgraph.

Les champs de requête de recherche en texte intégral, fournissent une Api de recherche de texte expressive qui peut être ajoutée au schéma de soubgraph et personnalisée. Reportez-vous à Définition des champs de recherche en texte intégral pour ajouter une recherche en texte intégral à votre subgraph.

Opérateurs de recherche en texte intégral :

SymboleOpérateurDescription
&AndPour combiner plusieurs termes de recherche dans un filtre pour les entités incluant tous les termes fournis
|OrLes requêtes comportant plusieurs termes de recherche séparés par l'opérateur ou renverront toutes les entités correspondant à l'un des termes fournis
<>Follow bySpécifiez la distance entre deux mots.
:*PrefixUtilisez le terme de recherche de préfixe pour trouver les mots dont le préfixe correspond (2 caractères requis.)

En utilisant l'opérateur ou, cette requête filtrera les entités de blog ayant des variations de "anarchism" ou "crumpet" dans leurs champs de texte intégral.

{
blogSearch(text: "anarchism | crumpets") {
id
title
body
author
}
}

L'opérateur follow by spécifie un mot à une distance spécifique dans les documents en texte intégral. La requête suivante renverra tous les blogs contenant des variations de "décentraliser" suivies de "philosophie"

{
blogSearch(text: "decentralized <-> philosophy") {
id
title
body
author
}
}

Combinez des opérateurs de texte intégral pour créer des filtres plus complexes. Avec un opérateur de recherche de prétexte combiné à un suivi de cet exemple, la requête fera correspondre toutes les entités de blog avec des mots commençant par « lou » suivi de « musique ».

{
blogSearch(text: "lou:* <-> music") {
id
title
body
author
}
}

Graph Node met en œuvre une validation basée sur les spécifications des requêtes GraphQL qu'il reçoit à l'aide de graphql-tools-rs, qui est basée sur l'implémentation de référence graphql-js. Les requêtes qui échouent à une règle de validation sont accompagnées d'une erreur standard - consultez la Spécification GraphQL pour en savoir plus.

Le schéma de votre source de données, c'est-à-dire les types d'entités, les valeurs et les relations disponibles pour l'interrogation, est défini par le Langage de définition d'interface GraphQL (IDL).

Les schémas GraphQL définissent généralement des types racine pour les requêtes, les abonnements et les mutations. Le graphe ne prend en charge que les requêtes. Le type racine Query pour votre subgraph est automatiquement généré à partir du schéma GraphQL inclus dans le manifeste de votre subgraph.

Note: Notre API n'expose pas les mutations car les développeurs sont censés émettre des transactions directement contre la blockchain sous-jacente à partir de leurs applications.

Tous les types GraphQL avec des directives @entity dans votre schéma seront traités comme des entités et doivent avoir un champ ID.

Note: Actuellement, tous les types de votre schéma doivent avoir une directive @entity. À l'avenir, nous traiterons les types sans directive @entity comme des objets de valeur, mais cela n'est pas encore possible.

Métadonnées du Subgraph

Lien vers cette section

Tous les subgraphs ont un objet _Meta_ auto-généré, qui permet d'accéder aux métadonnées du subgraph. Cet objet peut être interrogé comme suit :

{
_meta(block: { number: 123987 }) {
block {
number
hash
timestamp
}
deployment
hasIndexingErrors
}
}

Si un bloc est fourni, les métadonnées sont celles de ce bloc, sinon le dernier bloc indexé est utilisé. S'il est fourni, le bloc doit être postérieur au bloc de départ du subgraph et inférieur ou égal au bloc indexé le plus récent.

deployment est un identifiant unique, correspondant au CID IPFS du fichier subgraph.yaml.

block fournit des informations sur le dernier bloc (en tenant compte des contraintes de bloc transmises à _meta) :

  • hash : le hash du bloc
  • number: the block number
  • timestamp : l'horodatage du bloc, si disponible (ceci n'est actuellement disponible que pour les subgraphs indexant les réseaux EVM)

hasIndexingErrors est un booléen identifiant si le subgraph a rencontré des erreurs d'indexation au cours d'un bloc passé

Modifier une page

Précédente
Systèmes distribués
Suivante
Identifiant du Subgraph VS. Identifiant de déploiement
Modifier une page