💨

ZodのスキーマとPrismaのスキーマの二重管理は避けられないもの?

2023/06/26に公開
2

2023年4月頃からTypeScriptでWebアプリを作り始めており、一番悩んでいるのが、Formの実装です。人生で、初めてのFullStack TypeScript。

  1. ReactHookFormをTypeSafeに使い回すための設計
  2. 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スキーマのマイグレーションがあった時にプロパティの整合性をコンパイルエラーで検知できるようにして事故を防ぐ考え方なのかなと思いました。

https://zenn.dev/ynakamura/articles/65d58863563fbc

TypeScriptのメンター欲しい・・・ご興味を持っていただける方、ぜひご連絡ください。

Discussion

rocchoroccho

prisma限定ではないですが、同じ課題を抱えています。
その後いい方法は見つかりましたか?
ここ最近、zodファーストなRDBのマイグレーションないしクエリビルダーを継続して探しているところです。