スキーマ拡張
スキーマ拡張動的変数

動的変数

以下のGraphQLクエリは、変数$limitを受け取って取得する投稿数を決定します。変数の型Intは、オペレーションで宣言する必要があります:

query GetPosts($limit: Int) {
  posts(limit: $limit) {
    id
    title
  }
}

これはGraphQLにおける期待される動作であり、同じドキュメント内のJSONディクショナリで変数の値を提供します:

{
  "limit": 3
}

これは「静的」な動作であり、多くの言語で共通しています。たとえばPHPでは、以下のコードのように、関数の引数で型を指定できます。入力$numberは整数として定義されています:

function double(int $number): int
{
  return $number * 2;
}

さて、PHP関数の本体内で変数を宣言する場合、型を指定する必要はありません。変数の型は、その変数が使用されるコンテキストによって決まります。以下のコードでは、$doubleに整数値を代入することで、この変数が整数になります:

function double(int $number): int
{
  // This var is an integer, but we don't need to declare it
  $double = $number * 2;
  return $double;
}

カスタムディレクティブのおかげで、GraphQLサーバーは同様の動作を提供し、動的変数をサポートできます。動的変数は、クライアントから値を提供される代わりに、サーバーでクエリを解決する際に値が取得されます。

Gato GraphQLの**Multiple Query Execution**エクステンションには、カスタムディレクティブ@exportが付属しています。これにより、フィールドの値を(動的)変数にエクスポートし、別のオペレーションのフィールド引数でその変数の値を読み取ることができます:

query ExportLoggedInUserName {
  me {
    name @export(as: "userName")
  }
}
 
query GetPostsContainingString
  @depends(on: "ExportLoggedInUserName")
{
  posts(filter: { search: $userName }) {
    id
    title
  }
}

変数$userNameは動的であり、それを使用するオペレーション(GetPostsContainingString)で型(String)を定義する必要はありません。GraphQLサーバーはすでにコンテキストを理解しています。

以下のクエリのように、型が一致しない変数値を使用しようとした場合(Intが期待されているが、動的変数がStringの場合):

query ExportDynamicVariable {
  _echo(value: "Hello world!") @export(as: "stringVar") # Exported: String
}
 
query UseVariable
  @depends(on: "ExportDynamicVariable")
{
  posts(
    pagination: {
      limit: $stringVar # Expected: Int, received: String
    }
  ) {
    id
  }
}

...GraphQLサーバーは値の型変換に失敗し、エラーを返します:

{
  "errors": [
    {
      "message": "Cannot cast value 'Hello world!' for type 'Int'",
      "locations": [
        {
          "line": 10,
          "column": 13
        }
      ],
      "extensions": {
        "path": [
          "{limit: $stringVar}",
          "(pagination: {limit: $stringVar})",
          "posts(pagination: {limit: $stringVar}) { ... }",
          "query UseVariable @depends(on: \"ExportDynamicVariable\") { ... }"
        ],
        "type": "QueryRoot",
        "field": "posts(pagination: {limit: $stringVar}) { ... }",
        "id": "root",
        "code": "gql@5.6.1[16]",
        "specifiedBy": "https:\/\/spec.graphql.org\/draft\/#sec-Values-of-Correct-Type"
      }
    }
  ]
}

GraphQL仕様

この機能は現在GraphQL仕様の一部ではありませんが、以下で要望されています: