GraphQL API
Reading time: 9 min
This guide explains the GraphQL Query API that is used for The Graph Protocol.
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") {idowner}}
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 {idowner}}
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) {idowner}}
Från och med Graph Node 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) {idowner {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 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.
Fråga efter de första 10 tokens:
{tokens(first: 10) {idowner}}
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.
Fråga 10 Token
-enheter, förskjutna med 10 platser från början av samlingen:
{tokens(first: 10, skip: 10) {idowner}}
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 }) {idowner}}
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
.
Fråga utmaningar med failed
resultat:
{challenges(where: { outcome: "failed" }) {challengeroutcomeapplication {id}}}
Du kan använda suffix som _gt
, _lte
för värdejämförelse:
{applications(where: { deposit_gt: "10000000000" }) {idwhitelisteddeposit}}
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 } }) {idwhitelisteddeposit}}
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 } }) {challengeroutcomeapplication {id}}}
Från och med Graph Node 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" }] }) {challengeroutcomeapplication {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" }) {challengeroutcomeapplication {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" }] }) {challengeroutcomeapplication {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)
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. förklarar dessa begränsningar i detalj.
{challenges(block: { number: 8000000 }) {challengeroutcomeapplication {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" }) {challengeroutcomeapplication {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.
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 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:
Symbol | Operatör | Beskrivning |
---|---|---|
& | Och | För att kombinera flera söktermer till ett filter för entiteter som inkluderar alla de angivna termerna |
| | Eller | Fö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 av | Ange avståndet mellan två ord. |
:* | Prefix | Anvä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") {idtitlebodyauthor}}
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") {idtitlebodyauthor}}
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") {idtitlebodyauthor}}
Graph Node implementerar validering av de GraphQL-frågor den tar emot med hjälp av , som är baserad på . Frågor som misslyckas med en valideringsregel får ett standardfel - besök 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-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.
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 {numberhashtimestamp}deploymenthasIndexingErrors}}
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