API GraphQL
Reading time: 9 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.
Запрос на один объект Token
, определенный в Вашей схеме:
{token(id: "1") {idowner}}
Note: When querying for a single entity, the id
field is required, and it must be writen as a string.
Запрос всех объектов Токен
:
{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}}
Начиная с Graph Node, объекты можно сортировать на основе вложенных содержаний.
The following example shows tokens sorted by the name of their owner:
{tokens(orderBy: owner__name, orderDirection: asc) {idowner {name}}}
В настоящее время Вы можете осуществлять сортировку по одно уровневым типам String
или ID
в полях @entity
и @derivedFrom
. К сожалению, , сортировка по полям, которые являются массивами и вложенными объектами, еще не поддерживается.
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.
Запрос первых 10 токенов:
{tokens(first: 10) {idowner}}
Чтобы запросить группы объектов в середине коллекции, параметр skip
можно использовать в сочетании с параметром first
, чтобы пропустить указанное количество объектов, начиная с начала коллекции.
Запрос 10 объектов Token
, смещенных на 10 позиций от начала коллекции:
{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.
Вызовы запросов с результатом failed
:
{challenges(where: { outcome: "failed" }) {challengeroutcomeapplication {id}}}
Вы можете использовать такие суффиксы, как _gt
, _lte
для сравнения значений:
{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)
.
Это может быть полезно, если Вы хотите получить только объекты, которые изменились, например, с момента последнего опроса. Или, в качестве альтернативы, может быть полезно исследовать или отладить изменнения объектов в Вашем субграфе (в сочетании с фильтрацией блоков Вы можете изолировать только объекты, которые изменились в определенном блоке).
{applications(where: { _change_block: { number_gte: 100 } }) {idwhitelisteddeposit}}
Фильтрация по вложенным объектам возможна в полях с суффиксом _
.
Это может быть полезно, если Вы хотите получать только объекты, у которых объекты дочернего уровня удовлетворяют заданным условиям.
{challenges(where: { application_: { id: 1 } }) {challengeroutcomeapplication {id}}}
Начиная с Graph Node , Вы можете группировать несколько параметров в одном и том же аргументе where
с использованием операторов and
или or
для фильтрации результатов на основе более чем одного критерия.
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:. Вы можете упростить приведенный выше запрос, удалив оператор and
, передав подвыражение, разделенное запятыми.
{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}}}
Примечание. При построении запросов важно учитывать влияние на производительность использования оператора or
. Хотя or
могут быть полезными инструментами для расширения результатов поиска, они также могут повлечь значительные затраты. Одна из основных проблем с or
заключается в том, что это может привести к замедлению запросов. Это связано с тем, что or
требует от базы данных сканирования нескольких индексов, что может занять много времени. Чтобы избежать этих проблем, разработчикам рекомендуется использовать операторы and вместо или всякий раз, когда это возможно. Это обеспечивает более точную фильтрацию и может привести к более быстрым и точным запросам.
Полный список суффиксов параметров:
__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
Обратите внимание, что некоторые суффиксы поддерживаются только для определенных типов. Например, Boolean
поддерживает только _not
, _in
и _not_in
, а _
доступен только для типов объектов и интерфейсов.
Кроме того, в качестве части аргумента where
доступны следующие глобальные фильтры:
_change_block(number_gte: Int)
Вы можете запрашивать состояние своих объектов не только для последнего блока, который используется по умолчанию, но и для произвольного блока в прошлом. Блок, в котором должен выполняться запрос, можно указать либо по номеру блока, либо по его хэшу, включив аргумент block
в поля верхнего уровня запросов.
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}}}
Этот запрос вернет объекты Challenge
и связанные с ними объекты Application
в том виде, в каком они существовали сразу после обработки блока номер 8 000 000.
{challenges(block: { hash: "0x5a0b54d5dc17e0aadc383d2db43b0a0d3e029c4c" }) {challengeroutcomeapplication {id}}}
Этот запрос вернет объекты Challenge
и связанные с ними объекты Application
в том виде, в каком они существовали сразу после обработки блока с заданным хешем.
Поля запроса полнотекстового поиска предоставляют API-интерфейс содержательного текстового поиска, который можно добавить в схему субграфа и настроить. См. , чтобы добавить полнотекстовый поиск в свой субграф.
Запросы полнотекстового поиска имеют одно обязательное поле, text
, для предоставления поисковых запросов. В этом поле поиска text
можно использовать несколько специальных операторов полнотекстового поиска.
Полнотекстовые поисковые операторы:
Символ | Оператор | Описание |
---|---|---|
& | And | Для объединения нескольких условий поиска в фильтр для объектов, которые включают все указанные условия |
| | Or | Запросы с несколькими условиями поиска, разделенные оператором or, вернут все объекты, которые соответствуют любому из предоставленных условий |
<-> | Follow by | Укажите расстояние между двумя словами. |
:* | Prefix | Используйте поисковый запрос по префиксу, чтобы найти слова с соответствующим префиксом (необходимо 2 символа) |
Используя оператор or
, этот запрос отфильтрует объекты блога с вариантами «anarchism» или «crumpet» в их полнотекстовых полях.
{blogSearch(text: "anarchism | crumpets") {idtitlebodyauthor}}
Оператор follow by
указывает слова на определенном расстоянии друг от друга в полнотекстовых документах. Следующий запрос вернет все блоги с вариантами «decentralize», за которыми следует «philosophy»
{blogSearch(text: "decentralized <-> philosophy") {idtitlebodyauthor}}
Комбинируйте полнотекстовые операторы, чтобы создавать более сложные фильтры. С оператором поиска по префиксу в сочетании с запросом «follow by» будут найдены все объекты блога со словами, начинающимися с «lou», за которыми следует «music».
{blogSearch(text: "lou:* <-> music") {idtitlebodyauthor}}
Graph Node реализует проверку запросов GraphQL, которые получает с помощью , основанного на . Запросы, которые не соответствуют правилу проверки, вызывают стандартную ошибку. Подробнее см. в .
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.
Все типы GraphQL с директивами @entity
в Вашей схеме будут рассматриваться как объекты и должны иметь поле ID
.
Примечание. В настоящее время все типы в Вашей схеме должны иметь директиву @entity
. В будущем мы будем рассматривать типы без директивы @entity
как объекты значений, но это пока не поддерживается.
Все субграфы имеют автоматически сгенерированный объект _Meta_
, который обеспечивает доступ к метаданным субграфа. Запросить это можно следующим образом:
{_meta(block: { number: 123987 }) {block {numberhashtimestamp}deploymenthasIndexingErrors}}
Если предоставлен блок, метаданные относятся к этому блоку, в противном случае используется последний проиндексированный блок. Если предоставляется блок, он должен быть после начального блока субграфа и меньше или равен последнему проиндексированному блоку.
deployment
— это уникальный идентификатор, соответствующий CID IPFS файла subgraph.yaml
.
block
предоставляет информацию о последнем блоке (с учетом всех ограничений блока, переданных в _meta
):
- hash: хэш блока
- number: номер блока
- timestamp: временная метка блока, если она доступна (в настоящее время доступна только для субграфов, индексирующих сети EVM)
hasIndexingErrors
— логическое значение, определяющее, обнаружил ли субграф ошибки индексации в каком-то предыдущем блоке