Querying > GraphQL API

GraphQL API

Reading time: 9 min

This guide explains the GraphQL Query API that is used for The Graph Protocol.

Förfrågningar

Länk till detta avsnitt

I din delgrafig schema definierar du typer som kallas Entiteter. För varje typ av Entitet kommer ett entitet- och entiteter-fält att genereras på toppnivån av Query-typen. Observera att query inte behöver inkluderas högst upp i graphql-förfrågan när du använder The Graph.

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

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

Note: Vid sökning efter en enskild enhet krävs fältet id, och det måste vara en sträng.

Fråga alla Token-enheter:

{
tokens {
id
owner
}
}

När du frågar efter en samling kan parametern orderBy användas för att sortera efter ett specifikt attribut. Dessutom kan orderDirection användas för att ange sorteringsriktningen, asc för stigande eller desc för fallande.

{
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.

I följande exempel sorterar vi tokens efter namnet på deras ägare:

{
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.

När du frågar efter en samling kan parametern first användas för att paginera från början av samlingen. Det är värt att notera att standardsorteringsordningen är efter ID i stigande alfanumerisk ordning, inte efter skapelsetid.

Vidare kan parametern skip användas för att hoppa över enheter och paginera. t.ex. first:100 visar de första 100 enheterna och first:100, skip:100 visar de nästa 100 enheterna.

Frågor bör undvika att använda mycket stora skip-värden eftersom de i allmänhet fungerar dåligt. För att hämta ett stort antal objekt är det mycket bättre att bläddra igenom entiteter baserat på ett attribut som visas i det sista exemplet.

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

Om en klient behöver hämta ett stort antal entiteter är det mycket mer effektivt att basera frågor på ett attribut och filtrera efter det attributet. En klient kan till exempel hämta ett stort antal tokens med hjälp av den här frågan:

query manyTokens($lastID: String) {
tokens(first: 1000, where: { id_gt: $lastID }) {
id
owner
}
}

Första gången skickas frågan med lastID = "", och för efterföljande frågor sätts lastID till id-attributet för den sista entiteten i den föregående frågan. Detta tillvägagångssätt kommer att fungera betydligt bättre än att använda ökande skip-värden.

Du kan använda parametern where i dina frågor för att filtrera efter olika egenskaper. Du kan filtrera på flera värden inom parametern where.

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

Du kan också filtrera entiteter efter _change_block(number_gte: Int) - detta filtrerar entiteter som uppdaterades i eller efter det angivna blocket.

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.

I följande exempel filtrerar vi efter utmaningar med utfall lyckades och nummer större än eller lika med 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
}
}
}

I följande exempel filtrerar vi efter utmaningar med outcome succeeded eller number större än eller lika med 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.

Resultatet av en sådan förfrågan kommer inte att ändras över tid, det vill säga, att förfråga vid en viss tidigare block kommer att returnera samma resultat oavsett när det utförs, med undantag för att om du förfrågar vid ett block mycket nära huvudet av kedjan, kan resultatet ändras om det visar sig att blocket inte är på huvudkedjan och kedjan omorganiseras. När ett block kan anses vara slutgiltigt kommer resultatet av förfrågan inte att ändras.

Observera att den nuvarande implementationen fortfarande är föremål för vissa begränsningar som kan bryta mot dessa garantier. Implementeringen kan inte alltid avgöra om en given blockhash inte alls är på huvudkedjan eller om resultatet av en förfrågan med blockhash för ett block som ännu inte kan anses vara slutgiltigt kan påverkas av en samtidig omorganisering av block. De påverkar inte resultaten av förfrågningar med blockhash när blocket är slutgiltigt och känt att vara på huvudkedjan. Detta problem förklarar dessa begränsningar i detalj.

{
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.

Schemat för din datakälla - det vill säga de entitetstyper, värden och relationer som är tillgängliga för frågor - definieras genom GraphQL Interface Definition Langauge (IDL).

GraphQL-scheman definierar i allmänhet rottyper för queries, subscriptions och mutations. Grafen stöder endast queries. Rottypen Query för din subgraf genereras automatiskt från GraphQL-schemat som ingår i subgrafmanifestet.

Note: Vårt API exponerar inte mutationer eftersom utvecklare förväntas utfärda transaktioner direkt mot den underliggande blockkedjan från sina applikationer.

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