drizzle schemaから型を作成し、特定のフィールドを選択・除外・追加する方法
この記事では、drizzle-zod
を使ってスキーマから型を作成し、pick
やomit
を使って特定のフィールドを選択・除外したり、さらにフィールドを追加する方法について解説します。
小学生にもわかる説明version
データの型ってなぁに?
データの型(種類)というのは、情報がどんな形をしているかを決めるルールのことです。たとえば、数字か、文字か、メールアドレスか、みたいなことを決めます。
特定のフィールド(情報の一部)だけを使う方法
例: ジョンさんとそのプレゼント
-
基本の情報カード:
-
ジョンさんの情報カードには、次のようなことが書かれています:
ID: 1 名前: ジョン・ドウ メール: john@example.com
-
-
特定の情報だけを選ぶ(
pick
を使う):- ジョンさんの情報カードから「ID」と「名前」だけを取り出します。
import { z } from 'zod';
import { userSchema } from "@/db/schema";
import { createSelectSchema } from 'drizzle-zod';
// 情報カードをチェックする道具(スキーマ)を作る
const UserSelectSchema = createSelectSchema(userSchema);
// IDと名前だけを選ぶ
const SelectedUserSchema = UserSelectSchema.pick({
id: true,
name: true
});
// 情報がちゃんとあるかチェック
const isValidSelected = SelectedUserSchema.safeParse({
id: 1,
name: 'ジョン・ドウ'
}).success;
console.log(isValidSelected); // true(ちゃんとあるよ)
omit
を使う)
例: 秘密の情報を抜く(ジョンさんの情報カードから、秘密の情報(たとえばパスワード)を取り出さないようにする。
import { z } from 'zod';
import { userSchema } from "@/db/schema";
import { createSelectSchema } from 'drizzle-zod';
// 情報カードをチェックする道具(スキーマ)を作る
const UserSelectSchema = createSelectSchema(userSchema);
// パスワードを抜く
const WithoutPasswordSchema = UserSelectSchema.omit({
password: true
});
// 情報がちゃんとあるかチェック
const isValidWithoutPassword = WithoutPasswordSchema.safeParse({
id: 1,
name: 'ジョン・ドウ',
email: 'john@example.com'
}).success;
console.log(isValidWithoutPassword); // true(ちゃんとあるよ)
例: 新しい情報を追加する
ジョンさんの情報カードに、新しいフィールド(たとえば「役割」)を追加します。
import { z } from 'zod';
import { userSchema } from "@/db/schema";
import { createInsertSchema } from 'drizzle-zod';
// 情報カードをチェックする道具(スキーマ)を作る
const UserInsertSchema = createInsertSchema(userSchema);
// 新しい情報(役割)を追加する
const extendedUserSchema = {
...userSchema,
role: 'string'
};
// 新しいスキーマを作る
const ExtendedUserInsertSchema = createInsertSchema(extendedUserSchema);
// 情報がちゃんとあるかチェック
const isValidWithRole = ExtendedUserInsertSchema.safeParse({
id: 1,
name: 'ジェーン・ドウ',
email: 'jane@example.com',
role: 'admin'
}).success;
console.log(isValidWithRole); // true(ちゃんとあるよ)
3. 大人ぽい解説と技術的なロジックの説明version
以下では、これらの操作がどのように技術的に実現されているか詳しく説明します。
1. Zodとdrizzle-zodの基本
ZodはJavaScriptのオブジェクトを型安全に扱うためのバリデーションライブラリです。drizzle-zod
は、データベーススキーマから直接Zodスキーマを生成することで、この型安全性をデータベース操作に拡張するためのプラグインです。
createSelectSchema と createInsertSchema
- *
createSelectSchema
*は、データを取得(読み取り)する際に使うスキーマを生成します。- fetchしてきたデータのタイプを使ってタイプセーフにするために使う
- *
createInsertSchema
*は、データを挿入(書き込み)する際に使うスキーマを生成します。- フォームデータ等を送るときに、その型が正しいかを見るので主にバリデーションを行うときに使う
import { users } from "@/db/schema";
import { createInsertSchema, createSelectSchema } from 'drizzle-zod';
export const UserSelectSchema = createSelectSchema(users)
export const UserInsertSchema = createInsertSchema(users)
2. 型の選択、除外、追加
pick
で特定のフィールドを選択
Zodのpick
メソッドは、既存のスキーマから特定のフィールドだけを抽出して新しいスキーマを作成します。
const SelectedUserSchema = UserSelectSchema.pick({
id: true,
name: true
});
-
技術的ロジック:
-
pick
は、元のスキーマから指定されたフィールドを含む新しいスキーマを作成します。これにより、必要なフィールドだけをバリデーションをすることができます。
-
omit
で特定のフィールドを除外
Zodのomit
メソッドは、既存のスキーマから特定のフィールドを除外して新しいスキーマを作成します。
const WithoutPasswordSchema = UserSelectSchema.omit({
password: true
});
-
技術的ロジック:
-
omit
は、元のスキーマから指定されたフィールドを除外した新しいスキーマを作成します。これにより、不要なフィールドやセンシティブな情報をバリデーションしないようにできます。
-
新しいフィールドを追加
新しいフィールドを追加する際には、既存のスキーマに新たなフィールドをマージした上で新しいスキーマを作成します。
const extendedUserSchema = {
...userSchema,
role: 'string'
};
const ExtendedUserInsertSchema = createInsertSchema(extendedUserSchema);
-
技術的ロジック:
- 元のスキーマから新しいフィールドを追加することで新しいスキーマを定義します。これにより、元のスキーマを壊すことなく拡張することができます。
3. データバリデーションの実行
safeParse
メソッドを使用して、データがスキーマ通りになっているかどうかを検証します。
const isValidWithRole = ExtendedUserInsertSchema.safeParse({
id: 1,
name: 'ジェーン・ドウ',
email: 'jane@example.com',
role: 'admin'
}).success;
-
技術的ロジック:
-
safeParse
は、データがスキーマに従っているかどうかをチェックし、結果を返します。success
プロパティがtrue
ならバリデーションに成功したことを示します。
-
これの操作を組み合わせることで、データ操作の正確性と安全性を確保できます。drizzle-zod
とZod
の強力な機能を活用するとスキーマ定義とバリデーションを少ないコード量で実現でき、データベース操作に伴うリスクを大幅に軽減します。
4. まとめ
drizzle-zodは、型バリデーションライブラリです。型バリデーションとは、入力データの型チェックを行うことです。drizzle-zodを使うことで、入力データの型チェックを自動的に行い、プログラムの安全性と信頼性を向上させることができます。
drizzle-ormとdrizzle-zodを組み合わせることで、より効率的かつ安全に型定義を行うことができます。スキーマからtypeを生成できるので安全かつ効率的に開発を進めることができます!みなさんもぜひ使ってみてください!
Discussion