GraphQLを使用していると、「Cannot return null for non-nullable field "X"」というエラーに遭遇することがあります。このエラーは、非nullableとして定義されたフィールドに対してnull値が返されようとしたときに発生します。本記事では、このエラーの原因と解決方法について詳しく解説します。

エラーの原因

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

1. スキーマ定義とリゾルバーの不一致

2. データベースやAPI呼び出しからのnull値の返却

3. 条件分岐でのnull処理の不備

解決方法

1. スキーマの見直し

まず、スキーマ定義を確認し、問題のフィールドが本当に非nullableである必要があるかを検討します。もし、nullが許容される場合は、スキーマを修正します。

type User {
  id: ID!
  name: String  # '!' を削除してnullableに
}

2. リゾルバーの修正

リゾルバー関数内でnull値を適切に処理するようにコードを修正します。

const resolvers = {
  Query: {
    user: (parent, args, context) => {
      const user = getUserFromDatabase(args.id);
      if (!user) {
        throw new Error('User not found');
      }
      return user;
    }
  }
};

3. デフォルト値の設定

nullが返される可能性がある場合、デフォルト値を設定することで問題を回避できます。

const resolvers = {
  User: {
    name: (user) => user.name || 'Unknown'
  }
};

4. Optional Chainingの使用

JavaScriptのOptional Chaining演算子を使用して、安全にプロパティにアクセスします。

const resolvers = {
  User: {
    name: (user) => user?.name ?? 'Unknown'
  }
};

5. エラーハンドリングの改善

GraphQL APIにエラーハンドリング層を追加し、nullの代わりにエラーを返すようにします。

const { ApolloServer, ApolloError } = require('apollo-server');

const server = new ApolloServer({
  typeDefs,
  resolvers,
  formatError: (err) => {
    if (err.message.startsWith('Cannot return null')) {
      return new ApolloError('An unexpected error occurred', 'INTERNAL_SERVER_ERROR');
    }
    return err;
  },
});

まとめ

「Cannot return null for non-nullable field "X"」エラーは、GraphQLの型システムとデータの整合性を保つ上で重要な警告です。適切なスキーマ設計、リゾルバーの実装、そしてエラーハンドリングを行うことで、このエラーを効果的に解決し、より堅牢なGraphQL APIを構築することができます。

これらの方法を適用することで、アプリケーションの安定性と信頼性が向上し、開発者とユーザー双方にとってより良い体験を提供できるでしょう。