GraphQLを使用する開発者にとって、「Variable "$X" got invalid value; Expected type "Y"」というエラーメッセージは比較的よく遭遇する問題です。このエラーは、GraphQLクエリやミューテーションに渡された変数の型が、スキーマで定義された型と一致しない場合に発生します。本記事では、このエラーの原因と効果的な解決方法について詳しく解説します。

エラーの原因

このエラーが発生する主な理由は以下の通りです:

1. 変数の型が正しくない

2. 必須フィールドが欠けている

3. 列挙型の値が間違っている

4. nullが許可されていない箇所でnullが渡されている

解決方法

1. 変数の型を確認する

まず、クエリやミューテーションで使用している変数の型が、スキーマで定義されている型と一致しているか確認しましょう。例えば、整数型を期待しているところに文字列を渡していないか、確認してください。

# 正しい例
mutation ($id: Int!) {
  deleteUser(id: $id)
}

# 間違った例(文字列を渡している)
mutation ($id: String!) {
  deleteUser(id: $id)
}

2. 必須フィールドを確認する

オブジェクト型の変数を渡す場合、必須フィールドがすべて含まれているか確認してください。

# スキーマ
type User {
  name: String!
  age: Int!
}

# 正しい例
mutation ($user: UserInput!) {
  createUser(user: $user)
}

# 変数
{
  "user": {
    "name": "John Doe",
    "age": 30
  }
}

# 間違った例(ageフィールドが欠けている)
{
  "user": {
    "name": "John Doe"
  }
}

3. 列挙型の値を確認する

列挙型を使用している場合、渡している値がスキーマで定義された値の中に含まれているか確認してください。

# スキーマ
enum UserRole {
  ADMIN
  USER
  GUEST
}

# 正しい例
mutation ($role: UserRole!) {
  setUserRole(role: $role)
}

# 変数
{
  "role": "ADMIN"
}

# 間違った例(定義されていない値)
{
  "role": "SUPERUSER"
}

4. null値の扱いを確認する

非null型(`!`がついている型)の変数にnullを渡していないか確認してください。

# スキーマ
type Query {
  getUser(id: Int!): User
}

# 正しい例
query ($id: Int!) {
  getUser(id: $id) {
    name
  }
}

# 変数
{
  "id": 123
}

# 間違った例(nullを渡している)
{
  "id": null
}

エラーのデバッグ方法

1. GraphQLのプレイグラウンド(GraphiQL, GraphQL Playground等)を使用して、クエリやミューテーションをテストする。

2. 変数のJSONを慎重にチェックし、型や値が正しいか確認する。

3. スキーマの定義を再確認し、期待される型と実際に渡している型が一致しているか確認する。

まとめ

「Variable "$X" got invalid value; Expected type "Y"」エラーは、主に変数の型や値が期待されるものと異なる場合に発生します。このエラーを解決するには、スキーマの定義を十分に理解し、正しい型と値を変数として渡すことが重要です。また、GraphQLのツールを活用してデバッグを行うことで、より効率的にエラーを特定し解決することができます。

GraphQLの型システムを適切に理解し活用することで、より堅牢なアプリケーションの開発が可能になります。エラーメッセージをよく読み、スキーマとの整合性を常に意識することで、このような問題を未然に防ぐことができるでしょう。