13 分
GraphQL Validations Migration Guide
まもなく「graph-node」は GraphQL Validations 仕様 を 100% カバーします。
以前のバージョンの「graph-node」は、すべての検証をサポートしておらず、より適切な応答を提供していました。そのため、あいまいな場合、「graph-node」は無効な GraphQL 操作コンポーネントを無視していました。
GraphQL Validations サポートは、今後の新機能と The Graph Network の大規模なパフォーマンスの柱です。
また、The Graph Network の重要な要件であるクエリ応答の決定性も保証されます。
GraphQL Validations を有効にすると、The Graph API に送信された既存のクエリの一部が壊れます。
これらの検証に準拠するには、移行ガイドに従ってください。
⚠️ 検証がロールアウトされる前にクエリを移行しないと、エラーが返され、フロントエンド/クライアントが壊れる可能性があります。
移行ガイド
CLI 移行ツールを使用して、GraphQL 操作の問題を見つけて修正できます。または、GraphQL クライアントのエンドポイントを更新して、https://api-next.thegraph.com/subgraphs/name/$GITHUB_USER/$SUBGRAPH_NAME
エンドポイントを使用することもできます。このエンドポイントに対してクエリをテストすると、クエリの問題を見つけるのに役立ちます。
Not all Subgraphs will need to be migrated, if you are using GraphQL ESlint or GraphQL Code Generator, they already ensure that your queries are valid.
移行 CLI ツール
GraphQL 操作エラーのほとんどは、事前にコードベースで見つけることができます。
このため、開発中または CI で GraphQL 操作を検証するためのスムーズなエクスペリエンスを提供します。
@graphql-validate/cli
は、特定のスキーマに対して GraphQL 操作を検証するのに役立つシンプルな CLI ツールです。
入門
ツールは次のように実行できます。
1npx @graphql-validate/cli -s https://api-next.thegraph.com/subgraphs/name/$GITHUB_USER/$SUBGRAPH_NAME -o *.graphql
ノート:
- $GITHUB_USER、$SUBGRAPH_NAME を適切な値に設定または置き換えます。のように:
artblocks/art-blocks
- 提供されているプレビュー スキーマ URL (https://api-next.thegraph.com/) は大幅にレート制限されており、すべてのユーザーが新しいバージョンに移行すると廃止されます。 本番環境では使用しないでください。
- 操作は、次の拡張子を持つファイルで識別されます
.graphql
,.ts
,.tsx
,.js
,jsx
(-o
オプション)。
CLI 出力
[@graphql-validate/cli](https://github.com/saihaj/graphql-validate)
CLI ツールは、GraphQL 操作エラーを次のように出力します。

エラーごとに、説明、ファイル パスと位置、および解決例へのリンクが表示されます (次のセクションを参照)。
プレビュー スキーマに対してローカル クエリを実行する
検証がオンになっている「graph-node」バージョンを実行するエンドポイント「https://api-next.thegraph.com/」を提供します。
クエリを次の宛先に送信して試すことができます。
https://api-next.thegraph.com/subgraphs/id/<Qm...>
または
https://api-next.thegraph.com/subgraphs/name/<GITHUB_USER>/<SUBGRAPH_NAME>
検証エラーがあるとフラグが立てられたクエリを処理するには、Altair や GraphiQL などの好きな GraphQL クエリ ツールを使用して、クエリを試してみてください。これらのツールは、実行前であっても、UI でこれらのエラーをマークします。
問題を解決する方法
以下に、既存の GraphQL 操作で発生する可能性があるすべての GraphQL 検証エラーを示します。
GraphQL の変数、操作、フラグメント、または引数は一意である必要があります
操作に GraphQL 変数、操作、フラグメント、および引数の一意のセットが含まれるようにするためのルールを適用しました。
GraphQL 操作は、あいまいさが含まれていない場合にのみ有効です。
これを実現するには、GraphQL 操作の一部のコンポーネントが一意でなければならないことを確認する必要があります。
これらの規則に違反するいくつかの無効な操作の例を次に示します。
クエリ名が重複しています (#UniqueOperationNamesRule)
1# The following operation violated the UniqueOperationName2# rule, since we have a single operation with 2 queries3# with the same name4query myData {5 id6}78query myData {9 name10}
解決:
1query myData {2 id3}45query myData2 {6 # rename the second query7 name8}
フラグメント名の重複 (#UniqueFragmentNamesRule)
1# The following operation violated the UniqueFragmentName2# rule.3query myData {4 id5 ...MyFields6}78fragment MyFields {9 metadata10}1112fragment MyFields {13 name14}
解決:
1query myData {2 id3 ...MyFieldsName4 ...MyFieldsMetadata5}67fragment MyFieldsMetadata { # assign a unique name to fragment8 metadata9}1011fragment MyFieldsName { # assign a unique name to fragment12 name13}
重複した変数名 (#UniqueVariableNamesRule)
1# The following operation violates the UniqueVariables2query myData($id: String, $id: Int) {3 id4 ...MyFields5}
解決:
1query myData($id: String) {2 # keep the relevant variable (here: `$id: String`)3 id4 ...MyFields5}
引数名が重複しています (#UniqueArgument)
1# The following operation violated the UniqueArguments2query myData($id: ID!) {3 userById(id: $id, id: "1") {4 id5 }6}
解決:
1query myData($id: ID!) {2 userById(id: $id) {3 id4 }5}
重複した匿名クエリ (#LoneAnonymousOperationRule)
また、2 つの匿名操作を使用すると、応答構造の競合により、「LoneAnonymousOperation」ルールに違反します。
1# This will fail if executed together in2# a single operation with the following two queries:3query {4 someField5}67query {8 otherField9}
解決:
1query {2 someField3 otherField4}
または、2 つのクエリに名前を付けます。
1query FirstQuery {2 someField3}45query SecondQuery {6 otherField7}
重複するフィールド
GraphQL 選択セットは、最終的な結果セットを正しく解決する場合にのみ有効と見なされます。
特定の選択セットまたはフィールドが、選択されたフィールドまたは使用された引数のいずれかによってあいまいさを生み出す場合、GraphQL サービスは操作の検証に失敗します。
この規則に違反する無効な操作の例をいくつか示します。
競合するフィールド エイリアス (#OverlappingFieldsCanBeMergedRule)
1# Aliasing fields might cause conflicts, either with2# other aliases or other fields that exist on the3# GraphQL schema.4query {5 dogs {6 name: nickname7 name8 }9}
解決:
1query {2 dogs {3 name: nickname4 originalName: name # alias the original `name` field5 }6}
引数を持つフィールドの競合 (#OverlappingFieldsCanBeMergedRule)
1# Different arguments might lead to different data,2# so we can't assume the fields will be the same.3query {4 dogs {5 doesKnowCommand(dogCommand: SIT)6 doesKnowCommand(dogCommand: HEEL)7 }8}
解決:
1query {2 dogs {3 knowsHowToSit: doesKnowCommand(dogCommand: SIT)4 knowsHowToHeel: doesKnowCommand(dogCommand: HEEL)5 }6}
また、より複雑なユースケースでは、最終的に予想されるセットで競合を引き起こす可能性のある 2 つのフラグメントを使用して、この規則に違反する可能性があります。
1query {2 # Eventually, we have two "x" definitions, pointing3 # to different fields!4 ...A5 ...B6}78fragment A on Type {9 x: a10}1112fragment B on Type {13 x: b14}
それに加えて、@skip
や @include
などのクライアント側の GraphQL ディレクティブは、あいまいさにつながる可能性があります。次に例を示します。
1fragment mergeSameFieldsWithSameDirectives on Dog {2 name @include(if: true)3 name @include(if: false)4}
未使用の変数またはフラグメント
GraphQL 操作も、操作で定義されたすべてのコンポーネント (変数、フラグメント) が使用されている場合にのみ有効と見なされます。
これらのルールに違反する GraphQL 操作の例をいくつか示します:
未使用の変数 (#NoUnusedVariablesRule)
1# Invalid, because $someVar is never used.2query something($someVar: String) {3 someData4}
解決:
1query something {2 someData3}
未使用のフラグメント (#NoUnusedFragmentsRule)
1# Invalid, because fragment AllFields is never used.2query something {3 someData4}56fragment AllFields { # unused :(7 name8 age9}
解決:
1# Invalid, because fragment AllFields is never used.2query something {3 someData4}56# remove the `AllFields` fragment
無効または欠落している選択セット (#ScalarLeafsRule)
また、GraphQL フィールドの選択は、以下が検証された場合にのみ有効です:
- オブジェクト フィールドには選択セットが指定されている必要があります。
- エッジ フィールド (スカラー、列挙型) には、選択セットが指定されていてはなりません。
次のスキーマでこれらの規則に違反する例をいくつか示します:
1type Image {2 url: String!3}45type User {6 id: ID!7 avatar: Image!8}910type Query {11 user: User!12}
無効な選択セット
1query {2 user {3 id { # Invalid, because "id" is of type ID and does not have sub-fields45 }6 }7}
解決:
1query {2 user {3 id4 }5}
選択セットがありません
1query {2 user {3 id4 image # `image` requires a Selection-Set for sub-fields!5 }6}
解決:
1query {2 user {3 id4 image {5 src6 }7 }8}
引数の値が正しくない (#VariablesInAllowedPositionRule)
ハードコーディングされた値を引数に渡す GraphQL 操作は、スキーマで定義された値に基づいて有効である必要があります。
これらの規則に違反する無効な操作の例をいくつか示します:
1query purposes {2 # If "name" is defined as "String" in the schema,3 # this query will fail during validation.4 purpose(name: 1) {5 id6 }7}89# This might also happen when an incorrect variable is defined:1011query purposes($name: Int!) {12 # If "name" is defined as `String` in the schema,13 # this query will fail during validation, because the14 # variable used is of type `Int`15 purpose(name: $name) {16 id17 }18}
不明な型、変数、フラグメント、またはディレクティブ (#UnknownX)
不明なタイプ、変数、フラグメント、またはディレクティブが使用されている場合、GraphQL API はエラーを発生させます。
これらの不明な参照は修正する必要があります:
- タイプミスだった場合の名前の変更
- それ以外の場合は、削除します
フラグメント: 無効なスプレッドまたは定義
無効なフラグメント スプレッド (#PossibleFragmentSpreadsRule)
Fragment は、適用できない型に展開できません。
たとえば、Cat
フラグメントを Dog
タイプに適用することはできません。
1query {2 dog {3 ...CatSimple4 }5}67fragment CatSimple on Cat {8 # ...9}
無効なフラグメント定義 (#FragmentsOnCompositeTypesRule)
すべての Fragment は、(on ...
を使用して) 複合型、つまり、オブジェクト、インターフェイス、またはユニオンで定義する必要があります。
スカラーでのフラグメントの定義は無効であるため、次の例は無効です。
1ragment fragOnScalar on Int {2 # we cannot define a fragment upon a scalar (`Int`)3 something4}56fragment inlineFragOnScalar on Dog {7 ... on Boolean {8 # `Boolean` is not a subtype of `Dog`9 somethingElse10 }11}
ディレクティブの使用
ディレクティブはこの場所では使用できません (#KnownDirectivesRule)
The Graph API でサポートされている GraphQL ディレクティブ (@...
) のみを使用できます。
以下は、GraphQL がサポートするディレクティブの例です:
1query {2 dog {3 name @include(true)4 age @skip(true)5 }6}
_注: @stream
、@live
、@defer
はサポートされていません。
ディレクティブは、この場所で 1 回だけ使用できます (#UniqueDirectivesPerLocationRule)
The Graph でサポートされているディレクティブは、場所ごとに 1 回だけ使用できます。
以下は無効です (そして冗長です):
1query {2 dog {3 name @include(true) @include(true)4 }5}