Deno FreshアプリケーションのDB接続にPrisma Clientを使う
でPrismaとDenoの人たちによって着々と進められていたプロジェクトが成就しついにDeno DeployでPrismaが使えるようになったのでFreshから試してみた。
環境
- Deno Deployにデプロイする
- Prisma Data PlatformからDBサーバーに到達できる必要がある
- DBサーバーにはSupabase CloudのPostgreSQLを使う
Prisma Data Platform
PrismaのData Proxyという機能を利用するためのオフィシャルな方法。
Prisma ClientにDATABASE_URL="prisma://aws-us-east-1.prisma-data.com/?api_key=XXX"
のような接続先を設定するとHTTP越しにクエリが実行される。
Denoにはpostgresドライバ がありDeno Deployでも利用できるが現時点ではDeno経由でPrisma Clientのコードを実行するにはData Proxy経由で接続する必要がある
Freshアプリケーション作成
のとうり。FreshドキュメントにDB層をどう構築するのかは例がなく以下のようなIssueも立っている
Prisma Client構成
以下にドキュメントがある
schema.prismaをこう変更した
generator client {
provider = "prisma-client-js"
output = "../generated/client"
previewFeatures = ["deno"]
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model Event {
id Int @id @default(autoincrement())
createdAt DateTime @default(now())
}
環境変数を .env に記述。Prisma Data Platformの接続先を追加する
DATABASE_URL="prisma://aws-us-east-1.prisma-data.com/?api_key=XXX"
PRISMA_GENERATE_DATAPROXY="true"
migrateを使う版 DATABASE_MIGRATE_URL でダイレクトに postgres://
のSupabaseのホストを指定することができる。
db push/pull
は prisma://
ではできないのでこうした
DATABASE_URL="postgresql://postgres:PASSWORD@db.XXX.supabase.co:5432/postgres?schema=public" deno run -A --unstable npm:prisma db push
prisma generate
Prisma Clientのコードを生成する。PRISMA_GENERATE_DATAPROXY="true"でも--data-proxy
つけてもどちらでもよし
deno run -A --unstable npm:prisma generate --data-proxy
generated/
にdenoディレクトリができる
❯ tree generated/
generated/
└── client
├── deno
│ ├── edge.js
│ ├── edge.ts
│ ├── index.d.ts
│ └── polyfill.js
├── edge.d.ts
├── edge.js
├── index-browser.js
├── index.d.ts
├── index.js
├── libquery_engine-darwin-arm64.dylib.node
├── package.json
├── runtime
│ ├── edge-esm.js
│ ├── edge.js
│ ├── index-browser.d.ts
│ ├── index-browser.js
│ ├── index.d.ts
│ └── index.js
└── schema.prisma
API routesからDB接続
routes/api/counter.ts
を用意。アクセスする度にDBにINSERTしてカウントアップするようにした。
import { PrismaClient } from '../../generated/client/deno/edge.ts'
import { HandlerContext } from "$fresh/server.ts";
const prisma = new PrismaClient();
export const handler = async (_req: Request, _ctx: HandlerContext): Promise<Response> => {
await prisma.event.create({data:{}})
const count = await prisma.event.count()
return new Response(JSON.stringify({count}), {headers: {"Content-Type": "application/json"}});
};
❯ http http://localhost:8000/api/counter
HTTP/1.1 200 OK
content-length: 11
content-type: application/json
date: Thu, 20 Oct 2022 15:36:04 GMT
vary: Accept-Encoding
{
"count": 5
}
Deploy
DATABASE_URL="prisma://、、、
をDeno Deploy環境にも設定してデプロイする
Discussion