1秒まとめ
限定的ではあるが動く
動機
- Denoのnpm互換がリリースされてnode側の資産が利用できるようになってきた。
- 実際に使ってみると互換レイヤや対象パッケージの都合で使えないものも多い。
- WebAppを実装しようとしたときにDatabaseアクセス層としてPrismaが使えるかどうかが大きいと考えている。
- 現時点でDenoでPrisma(Prisma Client)を扱おうとしたときの筆者が知るつまづきポイントを纏めてみた
間違ってるよとかあれば優しくコメントで教えてほしい
公式にサポートしている動作方法
Deno + Prisma Client(preview Deno) + Primsa Data Proxy
- Deno(Prisma Client) -> Prisma Data Proxy -> Database で動作する
- Deno Deployでも動く
問題点
Data Proxy分のオーバーヘッドが常に掛かるようになる。
日本で使うとリージョンの問題で実際結構遅くなっちゃって不満
公式にサポートしていない動作方法
Deno + Prisma Client(library)
- Denoの
createRequire
で node互換のrequire
を利用して、生成されたPrisma Client libraryをロードする方法
問題点
Deno Deployでは動かない
Prisma Client libraryはその先でRustで書かれた Prisma Engine を ネイティブ拡張としてロードしている。このバイナリファイル(*.so.node)をロードする機構は Deno DeployのようなV8 isolateなEdge runtimeでサポートされていないので使えない
動作バージョンが限定的
prisma@4.12.0 以前まではこの方法でも動作したが、prisma@4.13.0で行われた変更 によって ネイティブ拡張のロードが require
から process.dlopen
に変化した影響で利用できなくなってしまった。
error: Uncaught Error: Unable to require(`/app/prisma/generated/client/libquery_engine-debian-openssl-1.1.x.so.node`).
The Prisma engines do not seem to be compatible with your system. Please refer to the documentation about Prisma's system requirements: https://pris.ly/d/system-requirements
Details: process.dlopen is not a function
at Yr.loadLibrary (file:///app/prisma/generated/client/runtime/library.js:106:777)
at eventLoopTick (ext:core/01_core.js:182:11)
at async rr.loadEngine (file:///app/prisma/generated/client/runtime/library.js:108:538)
at async rr.instantiateLibrary (file:///app/prisma/generated/client/runtime/library.js:107:1838)
Denoにも Deno.dlopen
というネイティブ拡張のロード機構は一応あるが、第三引数の flag
を渡す機構が存在しておらず また process.dlopen
もまだNode互換として実装されていない。
どうなっていくと良いと思うか
個人的には一番最後のWASM化が推し
Prisma Data Proxyの適合リージョンがDeno Deployの展開リージョンをサポートする
現時点では以下の2リージョンにData Proxyが展開されています。
- US East 1 (West Virginia, United States)
- EU Central 1 (Frankfurt, Germany)
DatabaseがAsia/Tokyoな場所に有るようなケースにおいて、Proxyを経由する為に一旦欧米を経由しなければいけないことがボトルネックになる要因なので、東京か大阪リージョンで利用できるようになればこの問題は一定軽減できることが期待できます。
一応新リージョンのリクエストフォームがあるようなので、リクエスト上げていけば解決するかも。
process.dlopenの互換実装をDeno側でサポートする
Support for passing flags in Deno.dlopen が解決した上で、process.dlopen
の互換実装がDenoから扱えるようになれば、prisma@4.13.0 移行でもDenoからPrisma Clientが利用できることが期待できます。
ただ、この解決策では引き続き Deno Deployでの利用はできません。
コンテナ化してCloudRunで動かしてるとかなら問題無いですが、Denoのエコシステムが使えないというのはあまり良い解決策では無いのかもしれない。
Denoチームに期待な解決策。
Prisma Engineのネイティブ拡張をWASM化
で詳しい。Prototype WebAssembly Engine in Prisma CLI で一部取り組みがすすんでいるが、Prisma EngineをWASMとして実行できるようになってくれれば Deno Deploy 含めエッジランタイムでも直接 DenoからPrisma Clientが扱えるようになる。
Prismaチームに期待な解決策。