API GraphQL
Reading time: 10 min
Learn about the GraphQL Query API used in The Graph.
is a query language for APIs and a runtime for executing those queries with your existing data. The Graph uses GraphQL to query subgraphs.
To understand the larger role that GraphQL plays, review and .
In your subgraph schema you define types called Entities
. For each Entity
type, entity
and entities
fields will be generated on the top-level Query
type.
Note: query
does not need to be included at the top of the graphql
query when using The Graph.
Requête pour une seule entité Token
définie dans votre schéma :
{token(id: "1") {idowner}}
Note: When querying for a single entity, the id
field is required, and it must be writen as a string.
Interrogez toutes les entités Token
:
{tokens {idowner}}
When querying a collection, you may:
- Use the
orderBy
parameter to sort by a specific attribute. - Use the
orderDirection
to specify the sort direction,asc
for ascending ordesc
for descending.
{tokens(orderBy : price, orderDirection : asc) {idpropriétaire}}
Depuis Graph Node , les entités peuvent être triées sur la base d'entités imbriquées.
The following example shows tokens sorted by the name of their owner:
{jetons (orderBy : propriétaire__nom, orderDirection : asc) {identifiantpropriétaire {{name}}}}
Actuellement, vous pouvez trier par types String
ou ID
profonds à un niveau sur les champs @entity
et @derivedFrom
. Malheureusement, le , le tri par champs qui sont des tableaux et des entités imbriquées est pas encore pris en charge.
When querying a collection, it's best to:
- Use the
first
parameter to paginate from the beginning of the collection.- The default sort order is by
ID
in ascending alphanumeric order, not by creation time.
- The default sort order is by
- Use the
skip
parameter to skip entities and paginate. For instance,first:100
shows the first 100 entities andfirst:100, skip:100
shows the next 100 entities. - Avoid using
skip
values in queries because they generally perform poorly. To retrieve a large number of items, it's best to page through entities based on an attribute as shown in the previous example above.
Interroger les 10 premiers tokens :
{tokens(first: 10) {idowner}}
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.
Interrogez 10 entités Token
, décalées de 10 places depuis le début de la collection :
{tokens(first: 10, skip: 10) {idowner}}
If a client needs to retrieve a large number of entities, it's more performant to base queries on an attribute and filter by that attribute. For example, a client could retrieve a large number of tokens using this query:
query manyTokens($lastID: String) {tokens(first: 1000, where: { id_gt: $lastID }) {idowner}}
The first time, it would send the query with lastID = ""
, and for subsequent requests it would set lastID
to the id
attribute of the last entity in the previous request. This approach will perform significantly better than using increasing skip
values.
- You can use the
where
parameter in your queries to filter for different properties. - You can filter on multiple values within the
where
parameter.
Afficher les défis (Challenges) avec résultat failed
(échec) :
{challenges(where: { outcome: "failed" }) {challengeroutcomeapplication {id}}}
Vous pouvez utiliser des suffixes comme _gt
, _lte
pour comparer les valeurs :
{applications(where: { deposit_gt: "10000000000" }) {idwhitelisteddeposit}}
You can also filter entities that were updated in or after a specified block with _change_block(number_gte: Int)
.
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 } }) {idwhitelisteddeposit}}
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 } }) {challengeroutcomeapplication {id}}}
Depuis Graph Node , 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.
The following example filters for challenges with outcome
succeeded
and number
greater than or equal to 100
.
{challenges(where: { and: [{ number_gte: 100 }, { outcome: "succeeded" }] }) {challengeroutcomeapplication {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" }) {challengeroutcomeapplication {id}}}
The following example filters for challenges with outcome
succeeded
or number
greater than or equal to 100
.
{challenges(where: { or: [{ number_gte: 100 }, { outcome: "succeeded" }] }) {challengeroutcomeapplication {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.
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)
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.
The result of such a query will not change over time, i.e., querying at a certain past block will return the same result no matter when it is executed, with the exception that if you query at a block very close to the head of the chain, the result might change if that block turns out to not be on the main chain and the chain gets reorganized. Once a block can be considered final, the result of the query will not change.
Note: The current implementation is still subject to certain limitations that might violate these guarantees. The implementation can not always tell that a given block hash is not on the main chain at all, or if a query result by a block hash for a block that is not yet considered final could be influenced by a block reorganization running concurrently with the query. They do not affect the results of queries by block hash when the block is final and known to be on the main chain. explains what these limitations are in detail.
{challenges(block: { number: 8000000 }) {challengeroutcomeapplication {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" }) {challengeroutcomeapplication {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é.
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 à 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 :
Symbole | Opérateur | Description |
---|---|---|
& | And | Pour combiner plusieurs termes de recherche dans un filtre pour les entités incluant tous les termes fournis |
| | Or | Les 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 by | Spécifiez la distance entre deux mots. |
:* | Prefix | Utilisez 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") {idtitlebodyauthor}}
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") {idtitlebodyauthor}}
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") {idtitlebodyauthor}}
Graph Node met en œuvre une validation des requêtes GraphQL qu'il reçoit à l'aide de , qui est basée sur l'implémentation de référence . Les requêtes qui échouent à une règle de validation sont accompagnées d'une erreur standard - consultez la pour en savoir plus.
The schema of your dataSources, i.e. the entity types, values, and relationships that are available to query, are defined through the .
GraphQL schemas generally define root types for queries
, subscriptions
and mutations
. The Graph only supports queries
. The root Query
type for your subgraph is automatically generated from the GraphQL schema that's included in your .
Note: Our API does not expose mutations because developers are expected to issue transactions directly against the underlying blockchain from their 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.
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 {numberhashtimestamp}deploymenthasIndexingErrors}}
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é