Release Notes & Upgrade Guides > Migrationsguide för GraphQL-validering

Migrationsguide för GraphQL-validering

Reading time: 8 min

Snart kommer graph-node att stödja 100 % täckning av GraphQL Valideringsspecifikationen.

Tidigare versioner av graph-node stödde inte alla valideringar och gav mer graciösa svar - så, i fall av oklarheter, ignorerade graph-node ogiltiga komponenter för GraphQL-operationer.

Stöd för GraphQL Validering är grundläggande för de kommande nya funktionerna och prestanda vid skala för The Graph Network.

Det kommer också att säkerställa determinism för frågesvar, en nyckelkrav på The Graph Nätverk.

Att aktivera GraphQL Validering kommer att bryta några befintliga frågor som skickas till The Graph API.

För att vara i linje med dessa valideringar, följ migrationsguiden.

⚠️ Om du inte migrerar dina frågor innan valideringarna tas i bruk kommer de att returnera fel och eventuellt bryta dina frontends/klienter.

Migrationsguide

Länk till detta avsnitt

Du kan använda CLI-migrationsverktyget för att hitta eventuella problem i dina GraphQL-operationer och åtgärda dem. Alternativt kan du uppdatera ändpunkten för din GraphQL-klient att använda ändpunkten https://api-next.thegraph.com/subgraphs/name/$GITHUB_USER/$SUBGRAPH_NAME. Att testa dina frågor mot denna ändpunkt kommer att hjälpa dig att hitta problemen i dina frågor.

Inte alla subgrafer behöver migreras, om du använder GraphQL ESlint eller GraphQL Code Generator, ser de redan till att dina frågor är giltiga.

Migrations-CLI-verktyg

Länk till detta avsnitt

De flesta felen i GraphQL-operationer kan hittas i din kodbas i förväg.

Av den anledningen erbjuder vi en smidig upplevelse för validering av dina GraphQL-operationer under utveckling eller i CI.

@graphql-validate/cli är ett enkelt CLI-verktyg som hjälper till att validera GraphQL-operationer mot ett givet schema.

Du kan köra verktyget enligt följande:

npx @graphql-validate/cli -s https://api-next.thegraph.com/subgraphs/name/$GITHUB_USER/$SUBGRAPH_NAME -o *.graphql

Noteringar:

  • Ange eller ersätt $GITHUB_USER, $SUBGRAPH_NAME med lämpliga värden. Som: artblocks/art-blocks
  • Förhandsgranskningsschema-URL:en (https://api-next.thegraph.com/) som tillhandahålls har en hög begränsning för antal begäranden och kommer att fasas ut när alla användare har migrerat till den nya versionen. Använd den inte i produktion.
  • Operationer identifieras i filer med följande filändelser .graphql,.ts, .tsx, .js, jsx (-o alternativ).

Verktyget [@graphql-validate/cli](https://github.com/saihaj/graphql-validate) för CLI kommer att ge utdata för eventuella fel i GraphQL-operationer enligt följande:

Felutdata från CLI

För varje fel hittar du en beskrivning, filväg och position, samt en länk till ett exempel på lösning (se följande avsnitt).

Kör dina lokala frågor mot förhandsgranskningschemat

Länk till detta avsnitt

Vi tillhandahåller en ändpunkt https://api-next.thegraph.com/ som kör en graph-node-version med aktiverad validering.

Du kan prova att skicka frågor till:

  • https://api-next.thegraph.com/subgraphs/id/<Qm...>

eller

  • https://api-next.thegraph.com/subgraphs/name/<GITHUB_USER>/<SUBGRAPH_NAME>

För att arbeta med frågor som har markerats med valideringsfel kan du använda din favorit-GraphQL-frågeverktyg, som Altair eller GraphiQL, och testa din fråga. Dessa verktyg kommer även att markera dessa fel i sitt användargränssnitt, även innan du kör det.

Hur man löser problem

Länk till detta avsnitt

Här nedan finner du alla fel för validering av GraphQL som kan uppstå i dina befintliga GraphQL-operationer.

GraphQL-variabler, operationer, fragment eller argument måste vara unika

Länk till detta avsnitt

Vi har tillämpat regler för att säkerställa att en operation inkluderar en unik uppsättning GraphQL-variabler, operationer, fragment och argument.

En GraphQL-operation är endast giltig om den inte innehåller någon oklarhet.

För att uppnå detta måste vi säkerställa att vissa komponenter i din GraphQL-operation måste vara unika.

Här är ett exempel på några ogiltiga operationer som bryter mot dessa regler:

Dubbel frågenamn (#UniqueOperationNamesRule)

# Följande åtgärd bröt mot UniqueOperationName
# regeln, eftersom vi har en enda åtgärd med 2 frågor
# med samma namn
query myData {
id
}
query myData {
name
}

Solution:

query myData {
id
}
query myData2 {
# Byt namn på den andra sökningen
namn
}

Duplikat Fragmentets namn (#UniqueFragmentNamesRule)

# Följande åtgärd bröt mot regeln UniqueFragmentName
# regel.
query myData {
id
...MyFields
}
fragment MyFields {
metadata
}
fragment MyFields {
name
}

Solution:

query myData {
id
...MyFieldsName
...MyFieldsMetadata
}
fragment MyFieldsMetadata { # tilldela ett unikt namn till fragmentet
metadata
}
fragment MyFieldsName { # tilldela ett unikt namn till fragmentet
namn
}

Dubbla variabelnamn (#UniqueVariableNamesRule)

# Följande operation strider mot UniqueVariables
query myData($id: String, $id: Int) {
id
...MyFields
}

Solution:

query myData($id: String) {
# behålla den relevanta variabeln (here: `$id: String`)
id
...MyFields
}

Dubbelnamn på argument (#UniqueArgument)

# Följande åtgärd bröt mot UniqueArguments
query myData($id: ID!) {
userById(id: $id, id: "1") {
id
}
}

Solution:

query myData($id: ID!) {
userById(id: $id) {
id
}
}

Dubbel anonym fråga (#LoneAnonymousOperationRule)

Att använda två anonyma operationer bryter också mot regeln LoneAnonymousOperation på grund av konflikt i svarsstrukturen:

# Detta kommer att misslyckas om det utförs tillsammans i
# en enda operation med följande två frågor:
query {
someField
}
query {
otherField
}

Solution:

query {
someField
otherField
}

Eller namnge de två frågorna:

query FirstQuery {
someField
}
query SecondQuery {
otherField
}

Överlappande fält

Länk till detta avsnitt

En GraphQL-urvalsuppsättning anses endast vara giltig om den korrekt löser den slutliga resultatuppsättningen.

Om en specifik urvalsuppsättning, eller ett fält, skapar tvetydighet antingen genom det valda fältet eller genom de argument som används, kommer GraphQL-tjänsten att misslyckas med att validera operationen.

Här är några exempel på ogiltiga operationer som bryter mot denna regel:

Aliaser för motstridiga fält (#OverlappingFieldsCanBeMergedRule)

# Aliasfält kan orsaka konflikter, antingen med
# andra alias eller andra fält som finns i
# GraphQL-schema.
query {
dogs {
name: nickname
name
}
}

Solution:

query {
dogs {
name: nickname
originalName: name # alias the original `name` field
}
}

Motstridiga fält med argument (#OverlappingFieldsCanBeMergedRule)

# Olika argument kan leda till olika data,
# så vi kan inte anta att fälten kommer att vara desamma.
query {
dogs {
doesKnowCommand(dogCommand: SIT)
doesKnowCommand(dogCommand: HEEL)
}
}

Solution:

query {
dogs {
knowsHowToSit: doesKnowCommand(dogCommand: SIT)
knowsHowToHeel: doesKnowCommand(dogCommand: HEEL)
}
}

I mer komplexa användningsfall kan du också bryta mot denna regel genom att använda två fragment som kan orsaka en konflikt i den slutligen förväntade uppsättningen:

query {
# Till slut har vi två "x"-definitioner, som pekar
# till olika fält!
...A
...B
}
fragment A on Type {
x: a
}
fragment B on Type {
x: b
}

Dessutom kan GraphQL-direktiv på klientsidan som @skip och @include leda till tvetydigheter, till exempel:

fragment mergeSameFieldsWithSameDirectives on Dog {
name @include(if: true)
name @include(if: false)
}

[Du kan läsa mer om algoritmen här] (https://spec.graphql.org/June2018/#sec-Field-Selection-Merging)

Oanvända variabler eller fragment

Länk till detta avsnitt

En GraphQL-operation anses också vara giltig endast om alla operationsdefinierade komponenter (variabler, fragment) används.

Här är några exempel på GraphQL-operationer som bryter mot dessa regler:

Oanvänd variabel (#NoUnusedVariablesRule)

# Ogiltig, eftersom $someVar aldrig används.
query something($someVar: String) {
someData
}

Solution:

query something {
someData
}

Oanvänt fragment (#NoUnusedFragmentsRule)

# Invalid, eftersom fragmentet AllFields aldrig används.
query something {
someData
}
fragment AllFields { # unused :(
name
age
}

Solution:

# Invalid, eftersom fragmentet AllFields aldrig används.
query something {
someData
}
# ta bort `AllFields` fragmentet

Ogiltig eller saknad urvalsuppsättning (#ScalarLeafsRule)

Länk till detta avsnitt

Dessutom är ett GraphQL-fältval endast giltigt om följande är validerat:

  • Ett objektfält måste ha en valuppsättning angiven.
  • Ett edge-fält (scalar, enum) får inte ha en specificerad urvalsuppsättning.

Här är några exempel på brott mot dessa regler med följande Schema:

type Image {
url: String!
}
type User {
id: ID!
avatar: Image!
}
type Query {
user: User!
}

Ogiltig urvalsuppsättning

query {
user {
id { # Invalid, eftersom "id" är av typen ID och inte xhar underfält
}
}
}

Solution:

query {
user {
id
}
}

Missande urvalsgrupp

query {
user {
id
image # `image` kräver en urvalssats för underfält!
}
}

Solution:

query {
user {
id
image {
src
}
}
}

Felaktiga argumentvärden (#VariablesInAllowedPositionRule)

Länk till detta avsnitt

GraphQL-operationer som skickar hårdkodade värden till argument måste vara giltiga, baserat på det värde som definieras i schemat.

Här följer några exempel på ogiltiga operationer som bryter mot dessa regler:

query purposes {
# Om "name" är definierat som "String" i schemat,
# kommer denna fråga att misslyckas under valideringen.
purpose(name: 1) {
id
}
}
# Detta kan också hända när en felaktig variabel definieras:
query purposes($name: Int!) {
# Om "name" är definierat som `String` i schemat,
# kommer denna fråga att misslyckas under valideringen, eftersom
# variabeln som används är av typen `Int`
purpose(name: $name) {
id
}
}

Okänd typ, variabel, fragment eller direktiv (#UnknownX)

Länk till detta avsnitt

GraphQL API kommer att ge ett felmeddelande om någon okänd typ, variabel, fragment eller direktiv används.

Dessa okända referenser måste åtgärdas:

  • Byt namn om det var ett stavfel
  • annars, ta bort

Fragment: ogiltig spridning eller definition

Länk till detta avsnitt

Ogiltig spridning av fragment (#PossibleFragmentSpreadsRule)

Ett Fragment kan inte spridas på en icke tillämplig typ.

Exempel: Vi kan inte tillämpa ett Cat-fragment på Dog-typen:

query {
dog {
...CatSimple
}
}
fragment CatSimple on Cat {
# ...
}

Ogiltig fragmentdefinition (#FragmentsOnCompositeTypesRule)

Alla Fragment måste definieras på (med on ...) en sammansatt typ, kort sagt: objekt, gränssnitt eller union.

Följande exempel är ogiltiga, eftersom det är ogiltigt att definiera fragment på skalärer.

fragment fragOnScalar on Int {
# vi kan inte definiera ett fragment på en skalär (`Int`)
något
}
fragment inlineFragOnScalar on Dog {
... on Boolean {
# `Boolean` är inte en subtyp av `Dog`
somethingElse
}
}

Användning av direktiv

Länk till detta avsnitt

Direktiv kan inte användas på denna plats (#KnownDirectivesRule)

Endast GraphQL-direktiv (@...) som stöds av The Graph API kan användas.

Här är ett exempel med de GraphQL-direktiv som stöds:

query {
dog {
name @include(true)
age @skip(true)
}
}

Note: @stream, @live, @defer stöds inte.

Direktivet kan endast användas en gång på denna plats (#UniqueDirectivesPerLocationRule)

De direktiv som stöds av The Graf kan endast användas en gång per plats.

Följande är ogiltigt (och överflödigt):

query {
dog {
name @include(true) @include(true)
}
}
Redigera sida

Tidigare
AssemblyScript Migrationsguide
Nästa
Underströmmar
Redigera sida