GraphQLを使用していると、「Cannot return null for non-nullable field "X"」というエラーに遭遇することがあります。このエラーは、nullを許可しないフィールドに対してnullが返されたときに発生します。本記事では、このエラーの原因と解決方法について詳しく説明します。
エラーの原因
このエラーは主に以下の理由で発生します:
1. スキーマ定義とリゾルバの不一致
2. データベースからのnullデータ
3. 外部APIからの予期しないレスポンス
解決方法
1. スキーマの見直し
まず、GraphQLスキーマを確認しましょう。問題のフィールドが本当にnon-nullableである必要があるかを再考します。もし可能であれば、フィールドをnullableに変更することでエラーを回避できます。
type Query {
user(id: ID!): User
}
type User {
id: ID!
name: String # nameをString!からStringに変更
}2. リゾルバの修正
リゾルバ関数内でnullチェックを行い、適切なデフォルト値を設定します。
const resolvers = {
Query: {
user: (parent, { id }, context) => {
const user = fetchUserFromDatabase(id);
return {
id: user.id,
name: user.name || 'Unknown' // nameがnullの場合はデフォルト値を設定
};
}
}
};3. エラーハンドリングの実装
Apollo ServerなどのGraphQLサーバーでは、カスタムエラーハンドリングを実装できます。これにより、nullが返された場合でもエラーをクライアントに適切に伝えることができます。
const server = new ApolloServer({
typeDefs,
resolvers,
formatError: (error) => {
if (error.message.startsWith('Cannot return null for non-nullable field')) {
return new Error('データの取得に失敗しました。後ほど再試行してください。');
}
return error;
},
});4. データの整合性確認
データベースやAPIからのデータが常に期待通りの形式で返されることを確認します。必要に応じて、データクレンジングやバリデーションを実装しましょう。
function validateUserData(user) {
if (!user.name) {
user.name = 'Unknown';
}
return user;
}
const resolvers = {
Query: {
user: async (parent, { id }, context) => {
const user = await fetchUserFromDatabase(id);
return validateUserData(user);
}
}
};まとめ
「Cannot return null for non-nullable field "X"」エラーは、GraphQLの型システムとデータの整合性に関する重要な問題を示しています。スキーマ設計の見直し、リゾルバの適切な実装、そしてデータの検証を通じて、このエラーを効果的に解決できます。これらの対策を実施することで、より堅牢なGraphQLアプリケーションを構築することができるでしょう。