GraphQLロゴGraphQL

バリデーション

型システムを使用することで、GraphQLクエリが有効かどうかを事前に判定できます。これにより、サーバーとクライアントは、ランタイムチェックに頼ることなく、無効なクエリが作成された際に開発者に効果的に通知できます。

Star Warsの例では、ファイルstarWarsValidation-test.tsに、さまざまな無効性を示す多くのクエリが含まれており、リファレンス実装のバリデータを実行するためのテストファイルとして使用できます。

まず、複雑な有効なクエリを見てみましょう。これは、前のセクションの例と同様のネストされたクエリですが、重複したフィールドはフラグメントに分割されています。

そして、このクエリは有効です。いくつかの無効なクエリを見てみましょう…

フラグメントは自分自身を参照したり、サイクルを作成したりすることはできません。これは、結果が無限に大きくなる可能性があるためです。! これは上記のクエリと同じですが、明示的な3レベルのネストがありません。

フィールドをクエリする際は、指定された型に存在するフィールドをクエリする必要があります。そのため、`hero`が`Character`を返す場合、`Character`上のフィールドをクエリする必要があります。その型には`favoriteSpaceship`フィールドがないため、このクエリは無効です。

フィールドをクエリし、スカラーまたは列挙型以外のものを返す場合は、フィールドから取得するデータ(返り値)を指定する必要があります。Heroは`Character`を返し、`name`や`appearsIn`などのフィールドを要求してきましたが、それを省略すると、クエリは無効になります。

同様に、フィールドがスカラーの場合、その上で追加のフィールドをクエリすることは意味がなく、そうするとクエリが無効になります。

前述のように、クエリは対象の型上のフィールドのみをクエリできます。`hero`をクエリすると`Character`が返されますが、クエリできるのは`Character`上に存在するフィールドだけです。しかし、R2-D2の主要機能をクエリしたい場合はどうすればよいでしょうか?

そのクエリは無効です。なぜなら、`primaryFunction`は`Character`上のフィールドではないからです。`Character`が`Droid`の場合に`primaryFunction`を取得し、そうでない場合はそのフィールドを無視したいという方法が必要です。これには、前に紹介したフラグメントを使用できます。`Droid`上で定義されたフラグメントを設定して含めることで、`primaryFunction`が定義されている場所でのみクエリするようにします。

このクエリは有効ですが、冗長です。名前付きフラグメントは、複数回使用する場合に上記で役立ちましたが、ここでは1回しか使用していません。名前付きフラグメントを使用する代わりに、インラインフラグメントを使用できます。これにより、クエリ対象の型を指定できますが、個別のフラグメントに名前を付ける必要はありません。

これはバリデーションシステムの表面をなぞったに過ぎません。GraphQLクエリが意味的に意味を持つように、多くのバリデーションルールが適用されています。「バリデーション」セクションで仕様書が詳細に説明しており、validationディレクトリには、仕様に準拠したGraphQLバリデータを実装するコードが含まれています。

続きを読む →実行