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?

サーバレスDBのNeonからDBファーストでPrismaを使ってスキーマを作りzodを連携して型解決をしたlambda(Node.js)を作成したメモ

Last updated at Posted at 2024-02-24

概要

前回はNeonに繋いでSQLを発行することを試した。
今回は、型を自動的に作成して使用することを試す。

大まかな手順

  1. Prismaでスキーマファイルを作成
  2. スキーマファイルにzodの連携情報を追記
  3. zodファイルをgenerate
  4. zodで型解決
  5. lambdaから使用

ソースコード

なお、この手順だとバンドルファイルが肥大化する。対応はPrisma + zod を使用したLambdaのファイルサイズ肥大を抑えるために Lambda Layersを利用したメモに追記。

準備

ライブラリのインストール

npm i zod @prisma/client 
npm i -D prisma zod-prisma-types

スキーマファイルの作成

schema.prisma
generator zod {
  provider = "zod-prisma-types"
}

generator client {
  provider = "prisma-client-js"
}

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

環境変数ファイルの設定

?sslmode=require&pgbouncer=trueのクエリが必要なことに注意 *

.env
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ファイルが作成される。

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 ライクな実装

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?