generated at
Prismaについて考える
概要
少しPrismaを試す機会があり、面白そうだったので所感や意見についてメモを残しておきます

Prismaのよいところ
生産性の高さ
DSLによるスキーマ管理の抽象化
型安全にクエリを記述でき、IDEなどによる補完の恩恵も受けやすい
シンプルかつ直感的なAPI
バックエンドのDBを抽象化してくれる (PostgreSQL/MySQL/MongoDB)
Prisma Studioなどのツールも提供してくれる
追記) Prisma TypedSQLという機能が新しく入りました
これはとてもいい機能だと思っています
各種プラットフォームとの連携
Prisma Data ProxyPrisma Data PlatformなどのPrisma公式のプラットフォームとの相性の良さについては期待できそうです
Cloudflare WorkersDeno Deployなど、各種クラウドサービスでの動作などは既存のORMよりも進んでいるように見える
MongoDBのサポート
PrismaによりMongoDBに対して仮想的にスキーマを持ち込むことができる
個人的には、PrismaRDBMSよりもむしろMongoDBクライアントとしての利用に価値があるのではないかと感じています。
多言語サポート
Goのクライアントなども提供されているようです。

競合
既存のORM
これらの既存のORMと比較した場合、PrismaCloudflare Workersなどのプラットフォームのサポートが進んでいる
また、タイプセーフにクエリを記述しやすい点においてはPrismaの方が勝っていると思います
クエリビルダー
KyselyDrizzle ORMなど、最近はタイプセーフにクエリを記述する機能をサポートするクエリビルダーが増えてきている
また、これらのクエリビルダーはCloudflare Workersなどでも動作し、Prismaとも競合する点が多い
Prismaと比較するとこれらはエンジンが必要ない分、よりフットプリントが小さいなどのメリットがありそうです (Cloudflare Workersなどの環境で利用しやすい)

逆に課題として感じたこと
スキーマの抽象化について
短期的に考えると、Prismaのスキーマの抽象化機能は生産性などにプラスに働くことは多いと思います。
ただ、長期的な運用を考えた際に、RDBMSが提供する行レベルセキュリティやトリガーなどの有用な機能が抽象化によって活用しにくくなってしまうのではないかというのは個人的に懸念として感じました。
個人的な好みとしては、スキーマ管理はあまり抽象化したくないというのもあります
PrismaにはスキーマのIntrospection機能があり、それによって既存のデータベーススキーマからPrisma Clientを生成することもできます
そのため、RDBMSの機能を積極的に活用したいケースでは、マイグレーションについてはPrismaに乗っからず、別のツールで管理するというのも手段としてあるのかもしれません。
ただし、Prisma v4.5.0PostgreSQL extensionのサポートが入るなどしており、PrismaとしてはこういったDB固有の機能へのサポートに対しては、比較的積極的なようにも見えるため杞憂の可能性もありそうです

複雑なビジネス/ドメインロジックの実装
Node.jsの既存のORMにはActive Recordパターン(Sequelize/TypeORM)やData Mapperパターン(TypeORM/MikroORM)を実装したものが多いかと思います。
例えば、RailsactiverecordなどのActive Recordパターンを実装したORMを利用する場合、モデルにドメインロジックと永続化に関わるロジックの両方を持たせて開発されるケースが多いと思います (どこにロジックを書くべきかがはっきりしている)
Prismaではこれらのどちらのパターンも実装されていません
自分がPrismaをはじめてさわった時に違和感を感じた点はここで、永続化に関するデザインパターンなどの観点からすると、Prismaは既存のORMよりも一世代分退行しているようにも見えました
後述するように、これはおそらくマイクロサービスサーバレスアーキテクチャーなどの分散アーキテクチャーの登場により、より単純なアプローチでも十分ワークすると考えられた結果なのではないかと推測しています
そのため、ドメイン/ビジネスロジックをどこに実装していくべきかは利用者側で考える必要が出てきそうです。
チュートリアル通りに素直にPrismaで実装しようとすると、ドメインモデル貧血症に陥るケースが考えられます (ただしドメインがシンプルなケースにおいては、これは大きな問題にはなりません)
いわゆるDDDに基づいて開発を進めていきたいというようなケースでは、Prismaが返却するDTOとアプリケーションのドメインモデルとの間でマッピングが余分に必要になるため、TypeORMMikroORMなどと比較すると却って使い勝手が悪くなってしまう、ということも考えられそうです。
この問題を解決するためなのかは定かではないですが、RedwoodではRedwoodRecordというPrismaをベースにActice Recordパターンを実装したORMが提供されていたりするようです。
追記) Prisma v4.7.0Prisma Client extensionsという機能がサポートされました。これを活用することで、ActiveRecordパターンを実装することなどもできそうです。また、そういったパッケージなども今後、コミュニティから登場しそうな気がします

個人的な意見・感想
Prismaは以下のようなケースにおいて非常に使い勝手が良いのではないかと思いました。
とにかく素早く動くものを作りたい/試したい場合
スキーマ管理やクエリの実行などの抽象化やTypeScriptによる補完などのサポートもあり、この点に関してはPrismaは非常に優秀だと思います
Next.jsなどでBFFを実装するようなケース
ビジネスロジックはBFFではなく背後のマイクロサービスなどで実装する
BFFのレイヤーでは基本的にシンプルなクエリしか投げない
Lambdaなどをベースにサーバーレスアーキテクチャーを採用するケース
Prisma Data Proxyによるコネクションプーリングが活かしやすい
一つ一つのFunctionがシンプルな実装でおさまるケースにおいては課題として挙げたことは対して問題にはならないはず
むしろPrismaが背後のDBの詳細について抽象化してくれることで、素早く開発や検証が行いやすくなりそうで、この分野ではとても使いやすいのではないかと思いました
Cloudflare WorkersDeno Deployなどのエッジ コンピューティングサービスを採用するケース
これも上記のLambdaなどのケースと同様
データベースとしてMongoDBを採用するケース
個人的にはマイクロサービスサーバレスアーキテクチャーなどに従って実装する場合、Prismaは向いていそうな気がしました。逆に古典的なモノリシックなアーキテクチャーに従って開発する場合、SequelizeTypeORM, MikroORMなどのORMの方が向いているのではないかと感じました (個人的には、十分な経験などがない限り、初手でのマイクロサービスサーバレスアーキテクチャーなどの採用は避けたほうがよいという考えです)

おそらく、PrismaBFFマイクロサービス, サーバーレスアーキテクチャーなどの登場を受けて、既存のORMと比較してより軽量なアプローチを採用したとしても十分にワークするのではないか、ということを念頭において開発・設計されているのではないかと感じました。

また、単純に型安全にクエリを書きたいということが目的の場合はsqlcpgtyped, kyselyなどのよりシンプルで軽量なパッケージもあります。採用を検討する際はそれらも検討するとよさそうに思いました。(TypeScriptでタイプセーフにSQLを実行する)

いくつか課題に感じたことはあげたものの、Prismaの開発やコミュニティは非常に活発な印象を受けていて、今後様々な機能などが追加されていく可能性も高いと思います。エコシステムやコミュニティが活発であれば、なにかしらの問題があったとしても将来的には改善される可能性が高いと思われます。

リンク