🤔
graphql-codegenと@prisma/clinetの間のデータマッピングで少しハマった話
事象
graphql-codegenで自動生成されるリゾルバー関数のなかにuser:()=>{}
が作成されている。あれ。。。?
この時codegenをウォッチモードで動かしていたので、編集中に保存して処理が走ってしまっただけかと思い、user:()=>{}
を削除するも、graphql-codegenが実行される度にuser:()=>{}
が復活していることに気づきました。
article/resolvers/Article.ts
import type { ArticleResolvers } from './../../types.generated';
export const Article: ArticleResolvers = {
// ここが毎回自動生成されてしまい、エラーが出てしまう
user: () => {
/* Article.user resolver is required because Article.user exists but ArticleMapper.user does not */
},
};
各種構成
graphql
schema.graphql
extend type Query {
article(id: String!): Article
}
type Article {
id: String!
title: String!
user: User! //原因箇所
}
prisma
schema.prisma
model User {
id String @id @default(cuid())
name String?
@@map("users")
}
model Article {
id String @id @default(cuid())
title String
creatorId String @map("creator_id")
user User @relation(fields: [creatorId], references: [id], onDelete: Cascade)
@@map("articles")
}
自動生成設定
原因
@prisma/clientで生成されたtype Article
の中には、参照先の{ user: User }
までは含まれていませんでした。
schema.mappers.ts(修正前)
export type { Article as ArticleMapper } from '@prisma/client';
// Article型の中身です。参照先のUserテーブルは型定義に含まれていません。
type Article = {
id: string;
title: string;
creatorId: string;
}
そのため、GraphqlのQueryのarticle(id: String!): Article
の期待する返り値と不整合が起きて、ArticleResolvers側で不整合を解消するための処理を追記するようにuser:()=>{}
が自動追加されます。
解決方法
結論ですが、prisma側のデータモデルとgraphql側のデータモデルのマッピングに不備があったせいで、毎回作成されていました。以下のように設定することでデータモデルの不整合を解消し、参照先テーブルの項目もprisma経由で取得することができました。
schema.mappers.ts(修正後)
import type { Article, User } from '@prisma/client';
export type ArticleMapper = Article & { user: User };
Discussion