9 minutes
GraphQL API
Learn about the GraphQL Query API used in The Graph.
What is GraphQL?
GraphQL 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 developing and creating a subgraph.
Queries with GraphQL
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.
Příklady
Query for a single Token
entity defined in your schema:
1{2 token(id: "1") {3 id4 owner5 }6}
Note: When querying for a single entity, the id
field is required, and it must be written as a string.
Query all Token
entities:
1{2 tokens {3 id4 owner5 }6}
Třídění
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.
Příklad
1{2 tokens(orderBy: price, orderDirection: asc) {3 id4 owner5 }6}
Příklad vnořeného třídění entit
As of Graph Node v0.30.0
entities can be sorted on the basis of nested entities.
The following example shows tokens sorted by the name of their owner:
1{2 tokens(orderBy: owner__name, orderDirection: asc) {3 id4 owner {5 name6 }7 }8}
Currently, you can sort by one-level deep String
or ID
types on @entity
and @derivedFrom
fields. Unfortunately, sorting by interfaces on one level-deep entities, sorting by fields which are arrays and nested entities is not yet supported.
Stránkování
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.
Example using first
Dotaz na prvních 10 tokenů:
1{2 tokens(first: 10) {3 id4 owner5 }6}
To query for groups of entities in the middle of a collection, the skip
parameter may be used in conjunction with the first
parameter to skip a specified number of entities starting at the beginning of the collection.
Example using first
and skip
Query 10 Token
entities, offset by 10 places from the beginning of the collection:
1{2 tokens(first: 10, skip: 10) {3 id4 owner5 }6}
Example using first
and id_ge
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:
1query manyTokens($lastID: String) {2 tokens(first: 1000, where: { id_gt: $lastID }) {3 id4 owner5 }6}
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.
Filtrování
- You can use the
where
parameter in your queries to filter for different properties. - You can filter on multiple values within the
where
parameter.
Example using where
Query challenges with failed
outcome:
1{2 challenges(where: { outcome: "failed" }) {3 challenger4 outcome5 application {6 id7 }8 }9}
You can use suffixes like _gt
, _lte
for value comparison:
Příklad filtrování rozsahu
1{2 applications(where: { deposit_gt: "10000000000" }) {3 id4 whitelisted5 deposit6 }7}
Příklad pro filtrování bloků
You can also filter entities that were updated in or after a specified block with _change_block(number_gte: Int)
.
To může být užitečné, pokud chcete načíst pouze entity, které se změnily například od posledního dotazování. Nebo může být užitečná pro zkoumání nebo ladění změn entit v podgrafu (v kombinaci s blokovým filtrem můžete izolovat pouze entity, které se změnily v určitém bloku).
1{2 applications(where: { _change_block: { number_gte: 100 } }) {3 id4 whitelisted5 deposit6 }7}
Příklad vnořeného filtrování entit
Filtering on the basis of nested entities is possible in the fields with the _
suffix.
To může být užitečné, pokud chcete načíst pouze entity, jejichž entity podřízené úrovně splňují zadané podmínky.
1{2 challenges(where: { application_: { id: 1 } }) {3 challenger4 outcome5 application {6 id7 }8 }9}
Logické operátory
As of Graph Node v0.30.0
you can group multiple parameters in the same where
argument using the and
or the or
operators to filter results based on more than one criteria.
AND
Operator
The following example filters for challenges with outcome
succeeded
and number
greater than or equal to 100
.
1{2 challenges(where: { and: [{ number_gte: 100 }, { outcome: "succeeded" }] }) {3 challenger4 outcome5 application {6 id7 }8 }9}
Syntactic sugar: You can simplify the above query by removing the and
operator by passing a sub-expression separated by commas.
1{2 challenges(where: { number_gte: 100, outcome: "succeeded" }) {3 challenger4 outcome5 application {6 id7 }8 }9}
OR
Operator
The following example filters for challenges with outcome
succeeded
or number
greater than or equal to 100
.
1{2 challenges(where: { or: [{ number_gte: 100 }, { outcome: "succeeded" }] }) {3 challenger4 outcome5 application {6 id7 }8 }9}
Note: When constructing queries, it is important to consider the performance impact of using the or
operator. While or
can be a useful tool for broadening search results, it can also have significant costs. One of the main issues with or
is that it can cause queries to slow down. This is because or
requires the database to scan through multiple indexes, which can be a time-consuming process. To avoid these issues, it is recommended that developers use and operators instead of or whenever possible. This allows for more precise filtering and can lead to faster, more accurate queries.
Všechny filtry
Úplný seznam přípon parametrů:
1_2_not3_gt4_lt5_gte6_lte7_in8_not_in9_contains10_contains_nocase11_not_contains12_not_contains_nocase13_starts_with14_starts_with_nocase15_ends_with16_ends_with_nocase17_not_starts_with18_not_starts_with_nocase19_not_ends_with20_not_ends_with_nocase
Please note that some suffixes are only supported for specific types. For example, Boolean
only supports _not
, _in
, and _not_in
, but _
is available only for object and interface types.
In addition, the following global filters are available as part of where
argument:
1_change_block(number_gte: Int)
Dotazy na cestování čase
You can query the state of your entities not just for the latest block, which is the default, but also for an arbitrary block in the past. The block at which a query should happen can be specified either by its block number or its block hash by including a block
argument in the toplevel fields of queries.
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. This issue explains what these limitations are in detail.
Příklad
1{2 challenges(block: { number: 8000000 }) {3 challenger4 outcome5 application {6 id7 }8 }9}
This query will return Challenge
entities, and their associated Application
entities, as they existed directly after processing block number 8,000,000.
Příklad
1{2 challenges(block: { hash: "0x5a0b54d5dc17e0aadc383d2db43b0a0d3e029c4c" }) {3 challenger4 outcome5 application {6 id7 }8 }9}
This query will return Challenge
entities, and their associated Application
entities, as they existed directly after processing the block with the given hash.
Fulltextové Vyhledávání dotazy
Fulltext search query fields provide an expressive text search API that can be added to the subgraph schema and customized. Refer to Defining Fulltext Search Fields to add fulltext search to your subgraph.
Fulltext search queries have one required field, text
, for supplying search terms. Several special fulltext operators are available to be used in this text
search field.
Operátory fulltextového vyhledávání:
Symbol | Operátor | Popis |
---|---|---|
& | And | Pro kombinaci více vyhledávacích výrazů do filtru pro entity, které obsahují všechny zadané výrazy |
| | Or | Dotazy s více hledanými výrazy oddělenými operátorem nebo vrátí všechny entity, které odpovídají některému z uvedených výrazů |
<-> | Follow by | Zadejte vzdálenost mezi dvěma slovy. |
:* | Prefix | Pomocí předponového výrazu vyhledejte slova, jejichž předpona se shoduje (vyžadovány 2 znaky) |
Příklady
Using the or
operator, this query will filter to blog entities with variations of either “anarchism” or “crumpet” in their fulltext fields.
1{2 blogSearch(text: "anarchism | crumpets") {3 id4 title5 body6 author7 }8}
The follow by
operator specifies a words a specific distance apart in the fulltext documents. The following query will return all blogs with variations of “decentralize” followed by “philosophy”
1{2 blogSearch(text: "decentralized <-> philosophy") {3 id4 title5 body6 author7 }8}
Kombinací fulltextových operátorů můžete vytvářet složitější filtry. S operátorem pretextového vyhledávání v kombinaci s operátorem follow by bude tento příklad dotazu odpovídat všem entitá blog se slovy začínajícími na “lou” a následovanými slovem “music”.
1{2 blogSearch(text: "lou:* <-> music") {3 id4 title5 body6 author7 }8}
Validace
Graph Node implements specification-based validation of the GraphQL queries it receives using graphql-tools-rs, which is based on the graphql-js reference implementation. Queries which fail a validation rule do so with a standard error - visit the GraphQL spec to learn more.
Schema
The schema of your dataSources, i.e. the entity types, values, and relationships that are available to query, are defined through the GraphQL Interface Definition Language (IDL).
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 subgraph manifest.
Note: Our API does not expose mutations because developers are expected to issue transactions directly against the underlying blockchain from their applications.
Entities
All GraphQL types with @entity
directives in your schema will be treated as entities and must have an ID
field.
Note: Currently, all types in your schema must have an @entity
directive. In the future, we will treat types without an @entity
directive as value objects, but this is not yet supported.
Metadata podgrafů
All subgraphs have an auto-generated _Meta_
object, which provides access to subgraph metadata. This can be queried as follows:
1{2 _meta(block: { number: 123987 }) {3 block {4 number5 hash6 timestamp7 }8 deployment9 hasIndexingErrors10 }11}
Pokud je uveden blok, metadata se vztahují k tomuto bloku, pokud ne, použije se poslední indexovaný blok. Pokud je blok uveden, musí se nacházet za počátečním blokem podgrafu a musí být menší nebo roven poslednímu Indevovaný bloku.
deployment
is a unique ID, corresponding to the IPFS CID of the subgraph.yaml
file.
block
provides information about the latest block (taking into account any block constraints passed to _meta
):
- hash: hash bloku
- číslo: číslo bloku
- timestamp: časové razítko bloku, pokud je k dispozici (v současné době je k dispozici pouze pro podgrafy indexující sítě EVM)
hasIndexingErrors
is a boolean identifying whether the subgraph encountered indexing errors at some past block