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.
Eseguire query di una singola entità Token
definita nello schema:
{token(id: "1") {idowner}}
Note: When querying for a single entity, the id
field is required, and it must be writen as a string.
Eseguire query di tutte le entità 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) {idowner}}
A partire da Graph Node le entità possono essere ordinate sulla base delle entità annidate.
The following example shows tokens sorted by the name of their owner:
{tokens(orderBy: owner__name, orderDirection: asc) {idowner {name}}}
Attualmente, è possibile ordinare per tipi di String
oppure ID
profondi un livello sui campi @entity
e @derivedFrom
. Purtroppo non è ancora supportato , l'ordinamento per campi che sono array e entità annidate.
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.
Eseguire query di primi 10 token:
{tokens(first: 10) {idowner}}
Per eseguire query di gruppi di entità nel mezzo di una collezione, il parametro skip
può essere usato insieme al parametro first
per saltare un numero specifico di entità a partire dall'inizio della collezione.
Eseguire query di 10 entità Token
, sfalsate di 10 posizioni rispetto all'inizio della collezione:
{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.
Query con esito failed
:
{challenges(where: { outcome: "failed" }) {challengeroutcomeapplication {id}}}
È possibile utilizzare suffissi come _gt
, _lte
per confrontare i valori:
{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)
.
Questo può essere utile se si vuole recuperare solo le entità che sono cambiate, ad esempio dall'ultima volta che è stato effettuato il polling. In alternativa, può essere utile per indagare o fare il debug di come le entità stanno cambiando nel subgraph (se combinato con un filtro di blocco, è possibile isolare solo le entità che sono cambiate in un blocco specifico).
{applications(where: { _change_block: { number_gte: 100 } }) {idwhitelisteddeposit}}
Il filtraggio sulla base di entità annidate è possibile nei campi con il suffisso _
.
Questo può essere utile se si vuole recuperare solo le entità il cui livello di figlio soddisfa le condizioni fornite.
{challenges(where: { application_: { id: 1 } }) {challengeroutcomeapplication {id}}}
A partire dalla versione Graph Node è possibile raggruppare più parametri nello stesso argomento where
usando gli operatori and
oppure or
per filtrare i risultati in base a più di un criterio.
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}}}
Syntactic sugar: Si può semplificare la query precedente eliminando l'operatore and
passando una sottoespressione separata da virgole.
{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}}}
Nota: Quando si costruiscono le query, è importante considerare l'impatto sulle prestazioni dell'uso dell'operatore or
. Sebbene or
possa essere uno strumento utile per ampliare i risultati della ricerca, può anche avere costi significativi. Uno dei problemi principali di or
è che può causare un rallentamento delle query. Questo perché or
richiede al database di eseguire la scansione di più indici, un processo che può richiedere molto tempo. Per evitare questi problemi, si consiglia agli sviluppatori di utilizzare gli operatori e al posto di o quando possibile. Ciò consente di effettuare filtri più precisi e di ottenere query più rapide e precise.
Elenco completo dei suffissi dei parametri:
__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
Si noti che alcuni suffissi sono supportati solo per tipi specifici. Ad esempio, Boolean
supporta solo _not
, _in
e _not_in
, mentre _
è disponibile solo per i tipi oggetto e interfaccia.
Inoltre, i seguenti filtri globali sono disponibili come parte dell'argomento where
:
_change_block(number_gte: Int)
È possibile effetuare query dello stato delle entità non solo per l'ultimo blocco, che è quello predefinito, ma anche per un blocco nel passato. Il blocco in cui deve avvenire una query può essere specificato dal suo numero di blocco o dal suo hash, includendo un argomento block
nei campi di livello superiore delle query.
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}}}
Questa query restituirà le entità Challenge
e le entità Application
ad esse associate, così come esistevano direttamente dopo l'elaborazione del blocco numero 8.000.000.
{challenges(block: { hash: "0x5a0b54d5dc17e0aadc383d2db43b0a0d3e029c4c" }) {challengeroutcomeapplication {id}}}
Questa query restituirà le entità Challenge
e le entità Application
ad esse associate, così come esistevano direttamente dopo l'elaborazione del blocco con l'hash indicato.
I campi di ricerca fulltext forniscono un'API di ricerca testuale espressiva che può essere aggiunta allo schema del subgraph e personalizzata. Fare riferimento a per aggiungere la ricerca fulltext al subgraph.
Le query di ricerca fulltext hanno un campo obbligatorio, text
, per fornire i termini di ricerca. In questo campo di ricerca text
sono disponibili diversi operatori speciali per il fulltext.
Operatori di ricerca fulltext:
Simbolo | Operatore | Descrizione |
---|---|---|
& | And | Per combinare più termini di ricerca in un filtro per le entità che includono tutti i termini forniti |
| | Or | Le query con più termini di ricerca separati dall'operatore Or restituiranno tutte le entità con una corrispondenza tra i termini forniti |
<-> | Follow by | Specifica la distanza tra due parole. |
:* | Prefisso | Utilizzare il termine di ricerca del prefisso per trovare le parole il cui prefisso corrisponde (sono richiesti 2 caratteri.) |
Utilizzando l'operatore or
, questa query filtrerà le entità blog con variazioni di "anarchism" o "crumpet" nei loro campi fulltext.
{blogSearch(text: "anarchism | crumpets") {idtitlebodyauthor}}
L'operatore follow by
specifica le parole a una distanza specifica nei documenti fulltext. La seguente query restituirà tutti i blog con variazioni di "decentralize" seguite da "philosophy"
{blogSearch(text: "decentralized <-> philosophy") {idtitlebodyauthor}}
Combinare gli operatori fulltext per creare filtri più complessi. Con un operatore di ricerca pretext combinato con un follow by questa query di esempio corrisponderà a tutte le entità del blog con parole che iniziano con "lou" seguite da "music".
{blogSearch(text: "lou:* <-> music") {idtitlebodyauthor}}
Graph Node implementa la validazione delle query GraphQL che riceve utilizzando , che si basa sull'. Le query che non rispettano una regola di validazione vengono segnalate con un errore standard - per saperne di più, visitare le .
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.
Tutti i tipi GraphQL con direttive @entity
nello schema saranno trattati come entità e devono avere un campo ID
.
Nota: Attualmente, tutti i tipi nello schema devono avere una direttiva @entity
. In futuro, i tipi senza direttiva @entity
saranno trattati come oggetti valore, ma questo non è ancora supportato.
Tutti i subgraph hanno un oggetto _Meta_
autogenerato, che fornisce accesso ai metadati del subgraph. Questo oggetto può essere interrogato come segue:
{_meta(block: { number: 123987 }) {block {numberhashtimestamp}deploymenthasIndexingErrors}}
Se viene fornito un blocco, i metadati si riferiscono a quel blocco, altrimenti viene utilizzato il blocco indicizzato più recente. Se fornito, il blocco deve essere successivo al blocco iniziale del subgraph e inferiore o uguale al blocco indicizzato più recente.
deployment
è un ID unico, corrispondente al CID IPFS del file subgraph.yaml
.
block
fornisce informazioni sull'ultimo blocco (tenendo conto di eventuali vincoli di blocco passati a _meta
):
- hash: l'hash del blocco
- numero: il numero del blocco
- timestamp: il timestamp del blocco, se disponibile (attualmente è disponibile solo per i subgraph che indicizzano le reti EVM)
hasIndexingErrors
è un booleano che identifica se il subgraph ha incontrato errori di indicizzazione in qualche blocco passato