0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Prismaのスキーマファイルを分割するのじゃ

Posted at

zennに書いた記事をそのまま転載しています。
手動なのでQiita側の記事はメンテが漏れるかもしれません。
https://zenn.dev/assign/articles/7ac032c4a2132f

はじめに

Prismaのスキーマファイルを分割しました。Prismaの標準機能としてmulti file schemaがサポートされており、この機能を利用しました。ナレッジをご紹介します。

分割の背景

弊社のバックエンドはモジュラモノリスな作りになっており、複数のプロダクトのテーブル設計が一つのスキーマファイルで管理されていました。それぞれのプロダクトが機能改修を行うたびにスキーマファイルは巨大化し、分割前時点で数千行にも及んでいました。

この状況により大きく2点の課題が発生していました。
1点目は、プロダクト間のコンフリクトです。複数のプロダクトがそれぞれ独自に同じファイルを編集するため、Prismaのスキーマファイルはコンフリクトが頻発していました。
2点目は、ファイルが巨大すぎて生成AIが読み取れないという問題です。弊社でもCursorやClaude Codeを初めとするAgentic Codingを開発フローに積極的に取り入れていますが、その際に、スキーマファイルが巨大で伴ってトークンを消費しすぎてしまうため、情報をコンテキストに渡すことに苦労していました(Claude Codeはうまくgrepなどを駆使してくれるのですが、限界はある)。

以前より3rdPartyのライブラリによってPrismaのスキーマを分割できることは知っていたのですが、直近のバージョンからPrismaの標準機能として複数のprismaファイルがサポートされるようになったため今回はそちらを利用することにしました。

PrismaのMulti File Schema

詳細はこちらを参照してください。

v6.7.0(今年の4月30日リリース)からGAになった機能です。以下のように models 配下にprismaファイルを配置することでprismaファイルを複数持つことができます。

.
├── migrations
├── models
│   ├── posts.prisma
│   ├── users.prisma
│   └── ... other `.prisma` files
└── schema.prisma

分割のベストプラクティス

公式ドキュメントいわく、以下の3つがベストプラクティスに上げられています。

  1. ドメインごとにファイルを分けること
    • 関連するモデルを同じファイルにまとめ、例えばユーザー関連は user.prisma、投稿関連は post.prisma など、ドメイン単位で整理する
  2. 明確な命名規則を使うこと
    • スキーマファイルには内容が一目で分かるような明確で簡潔な名前を付ける
  3. 「メイン」スキーマファイルを用意する
    • datasource や generator ブロックは1つのファイル(例: schema.prisma, main.prisma, base.prisma など)にまとめて記述する

ネストもできる

ちなみに公式ドキュメントには明確には書かれていないのですが、サブディレクトリを再帰的に探索する仕組みになっているため、フォルダを駆使してネストすることもできます。

なお、作業時のバージョンでは、サブディレクトリの再帰探索に一部不具合が見られました。
具体的には、

prisma/
├── schema.prisma
└── models/
    ├── foo/
    │   ├── user.prisma
    │   ...
    ├── bar/
    │   ├── user.prisma
    │   ...
    └── baz/
        ├── user.prisma
        ...

こういう構成だと再帰的な探索が行われませんでした。

prisma/
├── schema.prisma
└── models/
    ├── qux.prisma # これ
    ├── foo/
    │   ├── user.prisma
    │   ...
    ├── bar/
    │   ├── user.prisma
    │   ...
    └── baz/
        ├── user.prisma
        ...

上記のようにmodels直下にschemaを置くことで再帰的な読み込みが行われました(このあたり、検証などで何度か手戻り...)。

ビルド

node_modules配下に分割されたスキーマが最終的に一つのファイルに統合され、1つのschema.prismaが出力されています。

いざ分割

冒頭に記載の通り、複数のプロダクトの機能がモジュラモノリス的に1つのバックエンド基盤に構築されているため、それがわかるようにプロダクトごとのサブディレクトリを切ることにしました。

prisma/
├── schema.prisma
└── models/
    ├── master.prisma                  # 共通のマスタテーブル
    ├── career-change/                 # 転職版
    │   ├── user.prisma
    │   ...
    ├── new-graduate/                  # 新卒版
    │   ├── user.prisma
    │   ...
    └── engineer/                      # エンジニア版
        ├── user.prisma
        ...

作業としてはひたすら、分割をしてPRを出し、分割をしてPRを出しという作業になります。
スキーマ変更を伴わないリファクタリングであったため、CIでのユニットテスト・E2Eテストの通過をもって作業を進めました

分割と合わせてschemaのformatチェック

また、Prismaにはschemaのformat機能があるのですが、こちらが徹底されておらず、一部フォーマットが崩れていたため、分割と合わせてnpm scriptに記載 & CIでformat/validateチェックをいれるようにしました。

おわりに

今回はPrismaのスキーマファイル分割についてご紹介しました。些末な変更のように見えますが、特にAI駆動開発の文脈では威力を発揮するのではないかと思っています。今後も日々の機能開発の合間に、ちょっとした改善を試みていきたいと思います。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?