subgraphs > Querying > GraphQL API

GraphQL API

Reading time: 9 min

Learn about the GraphQL Query API used in The Graph.

What is GraphQL?

Länk till detta avsnitt

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

Länk till detta avsnitt

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.

Förfrågan efter en enda Token -entitet som är definierad i din schema:

{
token(id: "1") {
id
owner
}
}

Note: When querying for a single entity, the id field is required, and it must be writen as a string.

Fråga alla Token-enheter:

{
tokens {
id
owner
}
}

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 or desc for descending.
{
tokens(orderBy: price, orderDirection: asc) {
id
owner
}
}

Exempel på sortering av nästlade entiteter

Länk till detta avsnitt

Från och med Graph Node v0.30.0 kan entiteter sorteras på basis av nästlade entiteter.

The following example shows tokens sorted by the name of their owner:

{
tokens(orderBy: owner__name, orderDirection: asc) {
id
owner {
name
}
}
}

För närvarande kan du sortera efter String- eller ID-typer på en djup nivå i fälten @entity och @derivedFrom. Tyvärr stöds ännu inte sortering efter gränssnitt på en nivå djupa enheter sortering efter fält som är matriser och kapslade enheter.

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.
  • Use the skip parameter to skip entities and paginate. For instance, first:100 shows the first 100 entities and first: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.

Exempel med first

Länk till detta avsnitt

Fråga efter de första 10 tokens:

{
tokens(first: 10) {
id
owner
}
}

För att söka efter grupper av enheter i mitten av en samling kan parametern skip användas tillsammans med parametern first för att hoppa över ett angivet antal enheter med start i början av samlingen.

Exempel med first och skip

Länk till detta avsnitt

Fråga 10 Token-enheter, förskjutna med 10 platser från början av samlingen:

{
tokens(first: 10, skip: 10) {
id
owner
}
}

Exempel med first och id_ge

Länk till detta avsnitt

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 }) {
id
owner
}
}

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.

Exempel med where

Länk till detta avsnitt

Fråga utmaningar med failed resultat:

{
challenges(where: { outcome: "failed" }) {
challenger
outcome
application {
id
}
}
}

Du kan använda suffix som _gt, _lte för värdejämförelse:

Exempel på filtrering av intervall

Länk till detta avsnitt
{
applications(where: { deposit_gt: "10000000000" }) {
id
whitelisted
deposit
}
}

Exempel på blockfiltrering

Länk till detta avsnitt

You can also filter entities that were updated in or after a specified block with _change_block(number_gte: Int).

Detta kan vara användbart om du bara vill hämta enheter som har ändrats, till exempel sedan den senaste gången du pollade. Eller alternativt kan det vara användbart för att undersöka eller felsöka hur enheter förändras i din undergraf (om det kombineras med ett blockfilter kan du isolera endast enheter som ändrades i ett visst block).

{
applications(where: { _change_block: { number_gte: 100 } }) {
id
whitelisted
deposit
}
}

Exempel på filtrering av inbäddade entiteter

Länk till detta avsnitt

Filtrering baserat på inbäddade entiteter är möjligt i fälten med _ suffix.

Detta kan vara användbart om du vill hämta endast entiteter vars entiteter på barnnivå uppfyller de angivna villkoren.

{
challenges(where: { application_: { id: 1 } }) {
challenger
outcome
application {
id
}
}
}

Logiska operatorer

Länk till detta avsnitt

Från och med Graph Node v0.30.0 kan du gruppera flera parametrar i samma where-argument med hjälp av och eller eller operatorer för att filtrera resultat baserat på mer än en kriterium.

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" }] }) {
challenger
outcome
application {
id
}
}
}

Syntactic sugar: Du kan förenkla ovanstående fråga genom att ta bort and-operatorn och istället skicka ett underuttryck separerat med kommatecken.

{
challenges(where: { number_gte: 100, outcome: "succeeded" }) {
challenger
outcome
application {
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" }] }) {
challenger
outcome
application {
id
}
}
}

Note: När man konstruerar sökfrågor är det viktigt att ta hänsyn till hur användningen av operatorn or påverkar prestandan. Även om or kan vara ett användbart verktyg för att bredda sökresultaten, kan det också ha betydande kostnader. Ett av de största problemen med or är att det kan göra sökningar långsammare. Detta beror på att or kräver att databasen söker igenom flera index, vilket kan vara en tidskrävande process. För att undvika dessa problem rekommenderas att utvecklare använder och-operatorer istället för eller när det är möjligt. Detta möjliggör mer exakt filtrering och kan leda till snabbare och mer exakta frågor.

Fullständig lista över parametersuffix:

_
_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

Observera att vissa suffix endast stöds för specifika typer. Till exempel stöder Boolean endast _not, _in och _not_in, men _ är endast tillgängligt för objekt- och gränssnittstyper.

Dessutom är följande globala filter tillgängliga som en del av argumentet where:

_change_block(number_gte: Int)

Tidsreseförfrågningar

Länk till detta avsnitt

Du kan förfråga tillståndet för dina enheter inte bara för den senaste blocken, som är standard, utan också för en godtycklig block i det förflutna. Blocket vid vilket en förfrågan ska ske kan specifieras antingen med dess blocknummer eller dess blockhash genom att inkludera ett block-argument i toppnivåfälten för förfrågningar.

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.

{
challenges(block: { number: 8000000 }) {
challenger
outcome
application {
id
}
}
}

Denna fråga kommer att returnera Challenge-enheter och deras tillhörande Application-enheter, så som de existerade direkt efter bearbetning av block nummer 8.000.000.

{
challenges(block: { hash: "0x5a0b54d5dc17e0aadc383d2db43b0a0d3e029c4c" }) {
challenger
outcome
application {
id
}
}
}

Denna förfrågan kommer att returnera Challenge-entiteter och deras associerade Application-entiteter så som de fanns direkt efter bearbetning av blocket med den angivna hashen.

Fulltextsökförfrågningar

Länk till detta avsnitt

Fält för fulltextsökning ger en uttrycksfull textsöknings-API som kan läggas till i undergrafens schema och anpassas. Hänvisa till Definiera fält för fulltextsökning för att lägga till fulltextsökning i din undergraf.

Fulltextsökförfrågningar har ett obligatoriskt fält, text, för att tillhandahålla söktermer. Flera specialiserade fulltextoperatorer finns tillgängliga att användas i detta text-sökfält.

Fulltextsökoperatorer:

SymbolOperatörBeskrivning
&OchFör att kombinera flera söktermer till ett filter för entiteter som inkluderar alla de angivna termerna
|EllerFörfrågningar med flera söktermer separerade av ellipsen kommer att returnera alla entiteter med en matchning från någon av de angivna termerna
<->Följs avAnge avståndet mellan två ord.
:*PrefixAnvänd prefixsöktermen för att hitta ord vars prefix matchar (2 tecken krävs.)

Med hjälp av operatorn or filtreras denna fråga till bloggenheter med variationer av antingen "anarchism" eller "crumpet" i sina fulltextfält.

{
blogSearch(text: "anarchism | crumpets") {
id
title
body
author
}
}

Operatorn follow by anger ord som står på ett visst avstånd från varandra i fulltextdokumenten. Följande fråga kommer att returnera alla bloggar med variationer av "decentralisera" följt av "filosofi"

{
blogSearch(text: "decentralized <-> philosophy") {
id
title
body
author
}
}

Kombinera fulltextoperatorer för att skapa mer komplexa filter. Med en pretext-sökoperatör kombinerad med en follow by kommer detta exempel att matcha alla bloggenheter med ord som börjar med "lou" följt av "music".

{
blogSearch(text: "lou:* <-> music") {
id
title
body
author
}
}

Graph Node implementerar specifikationsbaserad validering av de GraphQL-frågor den tar emot med hjälp av graphql-tools-rs, som är baserad på graphql-js reference implementation. Frågor som misslyckas med en valideringsregel får ett standardfel - besök GraphQL spec för mer information.

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 Langauge (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.

Alla GraphQL-typer med @entity-direktiv i ditt schema kommer att behandlas som entiteter och måste ha ett ID-fält.

Note: För närvarande måste alla typer i ditt schema ha ett @entity-direktiv. I framtiden kommer vi att behandla typer utan ett @entity-direktiv som värdeobjekt, men detta stöds ännu inte.

Metadata för undergrafer

Länk till detta avsnitt

Alla subgrafer har ett autogenererat _Meta_-objekt, som ger tillgång till subgrafens metadata. Detta kan efterfrågas på följande sätt:

{
_meta(block: { number: 123987 }) {
block {
number
hash
timestamp
}
deployment
hasIndexingErrors
}
}

Om ett block anges är metadata från det blocket, om inte används det senast indexerade blocket. Om det anges måste blocket vara efter undergrafens startblock och mindre än eller lika med det senast indexerade blocket.

deployment är ett unikt ID som motsvarar IPFS CID för filen subgraph.yaml.

block ger information om det senaste blocket (med hänsyn till eventuella blockbegränsningar som skickas till _meta):

  • hash: blockets hash
  • nummer: blockets nummer
  • timestamp: blockets timestamp, om tillgänglig (detta är för närvarande endast tillgängligt för undergrafer som indexerar EVM-nätverk)

hasIndexingErrors är en boolean som identifierar om undergrafen stötte på indexeringsfel vid något tidigare block

Redigera sida

Tidigare
Distribuerade System
Nästa
Subgraph ID vs Deployment ID
Redigera sida