Udvikling af subgraf, del 2: Håndtering af arrays og identifikation af enheder

(ProtoFire.io)

(Del 1 ) | Del 2

Dette blogindlæg indeholder praktiske anbefalinger til, hvordan du bruger arrays effektivt og genererer enheds-ider, der er unikke og henvises til.

I del 1 af denne serie leverede vi en oversigt over underbilleder for at hjælpe udviklere med at forstå deres grundlæggende struktur. Derudover delte vi også vores indsigt i kortlægning og aggregering af data.

Denne gang vil vi diskutere yderligere to emner: håndtering af arrays og generering af ider til enheder, der er både unikke og let refererede til. Som en del af diskussionen vil vi give vores anbefalinger til, hvordan man effektivt administrerer arrays og navngiver enheder korrekt.

Håndtering af arrays effektivt

Tilføjelse af arrays til enheder er nyttigt i visse scenarier. For eksempel er der tilfælde, hvor vi har brug for at modellere en liste over adresser til en datakilde eller spore historiske ændringer for et bestemt felt over tid.

Uden forudgående viden om, hvordan arrays fungerer inden for underbilleder, kunne vi overveje oprettelse af et felt af en arraytype i en enhedstypedefinition (inden for schema.graphql -filen) og initialisering af et tomt array, hver gang der oprettes en ny enhed af samme type. Når nye data føjes til arrayet, kan vi skubbe dataene og gemme enheden. Selvom dette lyder intuitivt, fungerer det desværre ikke.

Manuel håndtering af arrays på underbilleder, specifikt i ovenstående scenarie, har et par advarsler. Når du får adgang til et array af en enhed, får du en kopi af arrayet. Hvis du tilføjer nye data og gemmer enheden, fungerer de således ikke, som du ville forvente, da du simpelthen ændrer en kopi af arrayet, mens originalen forbliver uændret.

For at opdatere den aktuelle matrix, kan vi placere kopien af ​​arrayet i en variabel og derefter ændre dataene. Dernæst kan vi indstille variablen som det nye array på enheden. På denne måde erstattes det gamle array med kopien. Denne proces med opdatering af arrayet er eksemplificeret i følgende kode.

// This won"t work
entity.numbers.push(BigInt.fromI32(1))
entity.save()// This will work
let numbers = entity.numbers
numbers.push(BigInt.fromI32(1))
entity.numbers = numbers
entity.save()

Selvom du kan opdatere et array på den måde, der er vist ovenfor, er det ikke en ideel løsning . Udover at være ubelejligt er der en anden grund til ikke manuelt at håndtere arrays – tidsrejser-forespørgsler. (Læs del 1 af serien for at lære mere om tidsrejser-forespørgsler.)

Det er kun muligt at udføre tidsrejser-forespørgsler, fordi underbilleder holder styr på alle ændringer i alle enhederne præsenterer alle de tid. Hvis der er mange enheder med matrixfelter, som ofte er store og opdateres, skal der også gemmes kopier af alle arrays. Dette koster præstationen og diskpladsen for enhver indeksator, der indekserer din undergraf.

I øjeblikket er Graphs hostede tjeneste den eneste aktive indekser, der er tilgængelig. I fremtiden kan flere indeksere deltage med tilføjelsen af ​​The Graphs decentrale netværk. Disse nye indeksatorer vil være i stand til at vælge, hvilke underbilleder der skal indekseres. Hvis din undergraf er dårligt optimeret på grund af arrays, vil den sandsynligvis ikke blive hentet af nogen indekser.

For at optimere vores arrays kan vi bruge @derivedFrom kommentar. Denne metode tillader, at ethvert matrixfelt, der er defineret i en enhedstype, automatisk udfyldes af alle enheder af den specificerede type, der er knyttet til den enhed, vi definerer. Følgende eksempel viser brugen af ​​@derivedFrom -noteringen.

type User @entity {
id: ID! positions: [Position!]! @derivedFrom(field: “user”)
}type Position @entity {
id: ID! user: User! # This is the ID String of the User
}

I eksemplet ovenfor har vi en bruger med en automatisk genereret liste over Position enheder. Når vores undergraf modtager en forespørgsel, der beder om placeringsfeltet for User -enheden, udfører undergrafen et omvendt opslag for alle enhederne Position knyttet til den specifikke User enhed i deres user felt. På denne måde er de sammenkædede enheder dem, der har streng-idet for andre enheder i et af dens felter.

Ved hjælp af @derivedFrom -bemærkningen kan vi definere enheden skriv, som vi ønsker til vores matrixdata, definer det felt, der bruges, når der udledes arrayet, og link det til den oprindelige enhed via deres ID. Der er også fordelen ved at kunne tilføje flere data (f.eks. Oprettelse eller opdatering af metadata) til de enheder, der repræsenterer matrixdataene. Da disse er fuldt udbyggede enheder, kan vi nemt opdatere dem ved at indlæse deres ider i stedet for at slå dem op i arrayet.

Mens vi håndterer arrays med @derivedFrom -noteringen er lettere, er der stadig nogle overvejelser, man skal være opmærksom på.For det første fungerer det kun med en-til-mange forhold. I mange-til-mange forhold har vi stadig brug for den ene side af ligningen til manuelt at håndtere arrayet. For det andet vil du ikke være i stand til at få adgang til array-dataene, mens undergrafen indekseres, da arrayet er befolket, når der spørges.

Oprettelse af en navngivning konvention for enheds-ider

Alle enheder defineret i schema.graphql -filen identificeres af et ID-felt, der er erklæret som en ID! type repræsenteret som en streng. ID-feltet er vigtigt, da det bruges til at indlæse, oprette og gemme enheder.

Da ID-feltet er det primære middel til at identificere en enhed, skal det altid være unikt. Når det er sagt, er det ikke svært at garantere det unikke ved et ID. Data til stede i indekstiden kan kombineres for at generere unikke ider. Følgende kode er et eksempel på dette.

event.transaction.hash.toHex() + "-" + 
event.logIndex.toString()

Ved at tage transaktions-hash af en begivenhed (unik for forskellige transaktioner) og tilføje den til logindekset for den bestemte begivenhed (som identificerer en begivenhed inden for en transaktion), kan vi generere et unikt sammensat ID. På denne måde kan vi identificere en bestemt enhed blandt andre enheder af samme type, forudsat at der kun oprettes en enkelt enhed til en enkelt begivenhed. Hvis det er nødvendigt, kan vi også tilføje flere data for entydigt at identificere et antal enheder oprettet i samme begivenhed. For eksempel kunne vi indstille en tæller for hver gang en enhed oprettes og føje værdien til den nyoprettede enhed.

Selvom det er praktisk at have en nem metode til at generere unikke ider til vores enheder, bør vi også stræber efter at generere ider, der er forudsigelige og kan refereres til. Hvis vi har enheder, der er relateret til en del af vores domæne, som sandsynligvis vil blive spurgt af slutbrugere via deres id, kan vi generere et id, der refererer til det domæne, vi arbejder på.

Som et eksempel, overvej et scenario, hvor vi opretter en Account -enhed på en DEX-undergraf. Denne Account -enhed gemmer brugerens saldo samt andre oplysninger. Hvis vi opretter enheds-idet baseret på transaktionshashen, kunne brugeren i første omgang søge efter den transaktion, der oprettede den og genskabe den, men den er ikke intuitiv. Et bedre alternativ ville være at oprette et ID baseret på brugerens Ethereum-adresse og om nødvendigt kombinere det med noget andet, der er relevant for domænet. På denne måde kan vi entydigt identificere en bestemt brugerkonto fra andre konti for den samme bruger.

Sammenfattende kan generiske unikke ider uden nogen domænespecifikke data være nyttige for enheder, der ikke opdateres konstant. Dette er ideelt for enheder, der er oprettet for at gemme metadata til domænespecifikke begivenheder, der forbruges fra et afledt array på en hovedenhed. For eksempel er generiske unikke ider bedre egnet til overførsler, mynter, forbrændinger og swaps.

På den anden side er domænespecifikke ider ideelle til hovedenheder og enhver anden enhed, der får hyppige opdateringer. Du bruger sandsynligvis en kombination af en Ethereum-adresse og nogle andre domænespecifikke ider. I de fleste tilfælde genererer en smart kontrakt unikke ider og logger dem på begivenhederne. Hvis dette ikke er tilfældet, skal du studere den smarte kontrakt og identificere, hvad der gør din enhed unik og bruge disse data til at generere et ID.

Som en sidebemærkning er toHex() og toHexString() metoder – ofte brugt til at generere IDer ud af adresser eller hashes – returnerer en lille streng. Dette betyder, at når du forespørger om en undergraf til enheder, skal den angivne ID-streng være små, da forespørgslen er skiftende på små og store bogstaver.

For mere information om undergrafudvikling, se grafens officiel dokumentation . Yderligere detaljer kan også findes i projektets GitHub-arkiv . Grafen har også et aktivt og voksende samfund klar til at hjælpe og besvare de opståede spørgsmål. Vi opfordrer alle, der er interesserede i at udvikle deres egne underbilleder, til at deltage i Graphs Discord-server .

Skriv et svar

Din e-mailadresse vil ikke blive publiceret. Krævede felter er markeret med *