概要
前回はNeonに繋いでSQLを発行することを試した。
今回は、型を自動的に作成して使用することを試す。
大まかな手順
- Prismaでスキーマファイルを作成
- スキーマファイルにzodの連携情報を追記
- zodファイルをgenerate
- zodで型解決
- lambdaから使用
なお、この手順だとバンドルファイルが肥大化する。対応はPrisma + zod を使用したLambdaのファイルサイズ肥大を抑えるために Lambda Layersを利用したメモに追記。
準備
ライブラリのインストール
npm i zod @prisma/client
npm i -D prisma zod-prisma-types
スキーマファイルの作成
generator zod {
provider = "zod-prisma-types"
}
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
環境変数ファイルの設定
※ ?sslmode=require&pgbouncer=true
のクエリが必要なことに注意 *
DATABASE_URL=postgresql://___user___:___password___@hoge.us-west-2.aws.neon.tech/main?sslmode=require&pgbouncer=true
DBファーストでスキーマの作成
npx prisma db pull
成功すると、schema.prisma
ファイルが更新される。
zodの定義ファイルの作成
npx prisma generate
成功すると、generate/zod/index.ts
ファイルが作成される。
import { z } from 'zod';
import { Prisma } from '@prisma/client';
// 省略
export const scenario_listSchema = z.object({
id: z.string(),
title: z.string(),
src: z.string(),
summary: z.string(),
detail: z.string(),
s3_key: z.string(),
created: z.coerce.date(),
updated: z.coerce.date(),
})
// 省略
型解決
import { NeonQueryFunction, neon } from '@neondatabase/serverless';
import { scenario_listSchema } from '@/prisma/generate/zod/index.ts';
import { z } from 'zod';
type ScenarioListItem = z.infer<typeof scenario_listSchema>;
export const getScenarioList = async (): Promise<ScenarioListItem> => {
const ret = await execQuery(
`SELECT id
, title
, src
, summary
, detail
, s3_key
, created
, updated
FROM scenario_list
ORDER BY updated desc
`,
);
const retJson = ret.map((r) => scenario_listSchema.parse(r));
return retJson;
};
let sql: NeonQueryFunction<false, false> | null = null;
function getClient () {
if (sql) return sql;
if (!process.env.DATABASE_URL) {
throw new Error('environment variable:DATABASE_URL is not defined');
}
sql = neon(process.env.DATABASE_URL);
return sql;
};
async function execQuery (query: string) {
const client = getClient();
const result = await client(query);
return result;
};
参考
Prisma Neon
【NextJs14】NextJs14 と 便利なライブラリ【#27 Neon Serverless Postgres】
NestJSに最適のORMを考えてみる(Prisma VS TypeORM)
TypescriptのSQLクエリビルダーのkyselyが快適
TypeScript用クエリービルダー「Kysely」でトランザクション、UPSERT、JOINを使ってみた
schema
zodを使ってJSON.parseしたオブジェクトをvalidationして型安全にしたい
zod-prisma-types
Zodを活用する
DBスキーマファーストな Prisma の型定義に対する zod の使い方 と Fragment colocation ライクな実装