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.
Consulta por un solo Token
definido en tu esquema:
{token(id: "1") {idowner}}
Note: When querying for a single entity, the id
field is required, and it must be writen as a string.
Consulta todas las entidades 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 partir de Graph Node , las entidades se pueden ordenar con base en entidades anidadas.
The following example shows tokens sorted by the name of their owner:
{tokens(orderBy: owner__name, orderDirection: asc) {idowner {name}}}
Actualmente, puedes ordenar por tipos String
o ID
de un solo nivel en campos @entity
y @derivedFrom
. Desafortunadamente, , la ordenación por campos que son matrices y entidades anidadas.
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.
Consulta los primeros 10 tokens:
{tokens(first: 10) {idowner}}
Para consultar grupos de entidades en medio de una colección, el parámetro skip
puede utilizarse junto con el parámetro first
para omitir un número determinado de entidades empezando por el principio de la colección.
Consulta 10 entidades Token
, desplazadas 10 lugares desde el principio de la colección:
{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.
Desafíos de consulta con resultado failed
:
{challenges(where: { outcome: "failed" }) {challengeroutcomeapplication {id}}}
Puedes utilizar sufijos como _gt
, _lte
para la comparación de valores:
{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)
.
Esto puede ser útil si buscas obtener solo las entidades que han cambiado, por ejemplo, desde la última vez que realizaste una encuesta. O, alternativamente, puede ser útil para investigar o depurar cómo cambian las entidades en tu subgrafo (si se combina con un filtro de bloque, puedes aislar solo las entidades que cambiaron en un bloque específico).
{applications(where: { _change_block: { number_gte: 100 } }) {idwhitelisteddeposit}}
El filtrado basado en entidades anidadas es posible en los campos con el sufijo _
.
Esto puede ser útil si estás buscando obtener solo entidades cuyas entidades de nivel inicial cumplan con las condiciones proporcionadas.
{challenges(where: { application_: { id: 1 } }) {challengeroutcomeapplication {id}}}
A partir de Graph Node puedes agrupar múltiples parámetros en el mismo argumento where
utilizando los operadores and
o or
para filtrar los resultados en base a más de 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}}}
Azúcar sintáctico: Puedes simplificar la consulta anterior eliminando el operador and
pasando una subexpresión separada por comas.
{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: Al construir consultas, es importante considerar el impacto en el rendimiento al utilizar el operador or
. Si bien or
puede ser una herramienta útil para ampliar los resultados de búsqueda, también puede tener costos significativos. Uno de los principales problemas con or
es que puede hacer que las consultas se vuelvan más lentas. Esto se debe a que or
requiere que la base de datos escanee múltiples índices, lo que puede ser un proceso que consume tiempo. Para evitar estos problemas, se recomienda que los desarrolladores utilicen los operadores and en lugar de or siempre que sea posible. Esto permite un filtrado más preciso y puede llevar a consultas más rápidas y precisas.
Lista completa de sufijos de parámetros:
__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
Ten en cuenta que algunos sufijos solo se admiten para tipos específicos. Por ejemplo, Boolean
solo admite _not
, _in
y _not_in
, pero _
está disponible solo para tipos de objeto e interfaz.
Además, los siguientes filtros globales están disponibles como parte del argumento where
:
_change_block(number_gte: Int)
Puedes consultar el estado de tus entidades no solo para el último bloque, que es el predeterminado, sino también para un bloque arbitrario en el pasado. El bloque en el que debe ocurrir una consulta se puede especificar por su número de bloque o su hash de bloque al incluir un argumento block
en los campos de nivel superior de las consultas.
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}}}
Esta consulta devolverá entidades Challenge
y sus entidades Application
asociadas, tal como existían directamente después de procesar el bloque número 8,000,000.
{challenges(block: { hash: "0x5a0b54d5dc17e0aadc383d2db43b0a0d3e029c4c" }) {challengeroutcomeapplication {id}}}
Esta consulta devolverá entidades Challenge
y sus entidades Application
asociadas, tal como existían directamente después de procesar el bloque con el hash dado.
Los campos de consulta de búsqueda de texto completo proporcionan una API de búsqueda de texto expresivo que se puede agregar al esquema del subgrafo y personalizar. Consulta para agregar búsqueda de texto completo a tu subgrafo.
Las consultas de búsqueda de texto completo tienen un campo obligatorio, text
, para proporcionar términos de búsqueda. Hay varios operadores especiales de texto completo disponibles para usar en este campo de búsqueda text
.
Operadores de búsqueda de texto completo:
Símbolo | Operador | Descripción |
---|---|---|
& | And | Para combinar varios términos de búsqueda en un filtro para entidades que incluyen todos los términos proporcionados |
| | O | Las consultas con varios términos de búsqueda separados por o el operador devolverá todas las entidades que coincidan con cualquiera de los términos proporcionados |
<-> | Follow by | Especifica la distancia entre dos palabras. |
:* | Prefijo | Utilice el término de búsqueda del prefijo para encontrar palabras cuyo prefijo coincida (se requieren 2 caracteres.) |
Con el operador or
, esta consulta filtrará las entidades de blog con variaciones de "anarchism" o "crumpet" en sus campos de texto completo.
{blogSearch(text: "anarchism | crumpets") {idtitlebodyauthor}}
El operador follow by
especifica palabras separadas por una distancia específica en los documentos de texto completo. La siguiente consulta devolverá todos los blogs con variaciones de "decentralize" seguido por "philosophy"
{blogSearch(text: "decentralized <-> philosophy") {idtitlebodyauthor}}
Combina operadores de texto completo para crear filtros más complejos. Con un operador de búsqueda de pretexto combinado con una consulta de seguimiento de este ejemplo, se buscarán coincidencias con todas las entidades del blog con palabras que comiencen con "lou" seguido de "music".
{blogSearch(text: "lou:* <-> music") {idtitlebodyauthor}}
Graph Node implementa una validación de las consultas de GraphQL que recibe mediante [graphql-tools-rs](https:// github.com/dotansimha/graphql-tools-rs#validation-rules), que se basa en [implementación de referencia de graphql-js]( /tree/main/src/validation). Las consultas que fallan en una regla de validación lo hacen con un error estándar: visita las para obtener más información.
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.
Todos los tipos de GraphQL con directivas @entity
en tu esquema se tratarán como entidades y deben tener un campo ID
.
Nota: Actualmente, todos los tipos en tu esquema deben tener una directiva @entity
. En el futuro, trataremos los tipos sin una directiva @entity
como objetos de valor, pero esto aún no se admite.
Todos los subgrafos tienen un objeto _Meta_
generado automáticamente, que brinda acceso a los metadatos del subgrafo. Esto se puede consultar de la siguiente manera:
{_meta(block: { number: 123987 }) {block {numberhashtimestamp}deploymenthasIndexingErrors}}
Si se proporciona un bloque, los metadatos corresponden a ese bloque; de lo contrario, se utiliza el bloque indexado más reciente. Si es proporcionado, el bloque debe ser posterior al bloque de inicio del subgrafo y menor o igual que el bloque indexado más reciente.
deployment
es un ID único, correspondiente al IPFS CID del archivo subgraph.yaml
.
block
proporciona información sobre el último bloque (teniendo en cuenta cualquier restricción de bloque pasada a _meta
):
- hash: el hash del bloque
- número: el número de bloque
- timestamp: la marca de tiempo del bloque, en caso de estar disponible (actualmente solo está disponible para subgrafos que indexan redes EVM)
hasIndexingErrors
es un valor booleano que identifica si el subgrafo encontró errores de indexación en algún bloque anterior