11 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.
例
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}
並べ替え
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.
例
1{2 tokens(orderBy: price, orderDirection: asc) {3 id4 owner5 }6}
ネストされたエンティティの並べ替えの例
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.
ページネーション
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
最初の 10 個のトークンを照会します。
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.
フィルタリング
- 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:
範囲フィルタリングの例
1{2 applications(where: { deposit_gt: "10000000000" }) {3 id4 whitelisted5 deposit6 }7}
ブロックフィルタリングの例
You can also filter entities that were updated in or after a specified block with _change_block(number_gte: Int)
.
これは、前回のポーリング以降など、変更されたエンティティのみをフェッチする場合に役立ちます。または、サブグラフでエンティティがどのように変化しているかを調査またはデバッグするのに役立ちます (ブロック フィルターと組み合わせると、特定のブロックで変更されたエンティティのみを分離できます)。
1{2 applications(where: { _change_block: { number_gte: 100 } }) {3 id4 whitelisted5 deposit6 }7}
ネストされたエンティティ フィルタリングの例
Filtering on the basis of nested entities is possible in the fields with the _
suffix.
これは、子レベルのエンティティが指定された条件を満たすエンティティのみをフェッチする場合に役立ちます。
1{2 challenges(where: { application_: { id: 1 } }) {3 challenger4 outcome5 application {6 id7 }8 }9}
論理演算子
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.
すべてのフィルター
パラメータのサフィックスの全リスト:
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)
タイムトラベル クエリ
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.
例
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.
例
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.
全文検索クエリ
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.
全文検索演算子:
シンボル | オペレーター | 説明書き |
---|---|---|
& | And | 複数の検索語を組み合わせて、指定したすべての検索語を含むエンティティをフィルタリングします。 |
| | Or | 複数の検索語をオペレーターで区切って検索すると、指定した語のいずれかにマッチするすべてのエンティティが返されます。 |
<-> | Follow by | 2 つの単語の間の距離を指定します。 |
:* | Prefix | プレフィックス検索語を使って、プレフィックスが一致する単語を検索します(2 文字必要) |
例
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}
全文演算子を組み合わせて、より複雑なフィルターを作成します。口実検索演算子を follow by このサンプル クエリと組み合わせて使用すると、“lou” で始まり、その後に “music” が続く単語を持つすべてのブログ エンティティが一致します。
1{2 blogSearch(text: "lou:* <-> music") {3 id4 title5 body6 author7 }8}
認証
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.
スキーマ
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.
エンティティ
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.
サブグラフ メタデータ
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}
ブロックが提供されている場合、メタデータはそのブロックのものであり、そうでない場合は、最新のインデックス付きブロックが使用されます。提供される場合、ブロックはサブグラフの開始ブロックの後にあり、最後にインデックス付けされたブロック以下でなければなりません。
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: ブロックのハッシュ
- number: ブロック番号
- timestamp: 可能であれば、ブロックのタイムスタンプ (これは現在、EVMネットワークのインデックスを作成するサブグラフでのみ利用可能)
hasIndexingErrors
is a boolean identifying whether the subgraph encountered indexing errors at some past block