💨
ZodのスキーマとPrismaのスキーマの二重管理は避けられないもの?
2023年4月頃からTypeScriptでWebアプリを作り始めており、一番悩んでいるのが、Formの実装です。人生で、初めてのFullStack TypeScript。
- ReactHookFormをTypeSafeに使い回すための設計
- ZodとPrismaのスキーマの二重管理
1のRHFについては、色々参考になる記事があるのでなんとなく方向性は見えたんですが、2のZodとPrisma(要はDBテーブルのスキーマ)が二重管理になるのは、どうしようもなさそうな気配を感じています。
以下の event
というテーブルがあるとします。
CREATE TABLE `event` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`event_name` varchar(60) NOT NULL DEFAULT '',
`startDate` date NOT NULL,
`endDate` date NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
このテーブルスキーマから、コード生成等で 以下のZodのスキーマの元ネタ作る的なことを、皆さんやっているのかなって思ったけど、そういう話が見つけられなかった。CHECK制約入ってればENUMができるとか。
export const EventSchema = z.object({
id: z.number().int(),
eventName: z.string().max(60),
startDate: z.coerce.date(),
endDate: z.coerce.date(),
});
上記のスキーマだけだと実運用は使えない。ビジネス上のバリデーションが入るから。上記の例で言えば、startDate > endDate
の場合はNG。refine
でカバーしないといけない領域があるから、元々二重メンテ前提でしゃーない、が現実解なのかな?
Flaskで書いていたときも、WTFormとSQLAlchemyのスキーマが似て非なるものになって二重メンテ。pydanticになっても、完全に同一化することは難しかった。
DBスキーマのマイグレーションがあった時にプロパティの整合性をコンパイルエラーで検知できるようにして事故を防ぐ考え方なのかなと思いました。
TypeScriptのメンター欲しい・・・ご興味を持っていただける方、ぜひご連絡ください。
Discussion
prisma限定ではないですが、同じ課題を抱えています。
その後いい方法は見つかりましたか?
ここ最近、zodファーストなRDBのマイグレーションないしクエリビルダーを継続して探しているところです。
@Por
prisma.schemaからZodのスキーマを、
zod-prisma-types
で生成できました。色んなカスタマイズができそうなので、これをもう少し追いかけていこうと思っています。