ZenStack を使用してデータベーススキーマを作成する
はじめに
Prisma でデータベーススキーマを書く際に、ZenStack というフレームワークが便利だったので紹介します。 ZenStack にはさまざまな機能がありますが、今回はデータベーススキーマの定義について重点的に説明します。
ZenStack とは
ZenStack は、Node.js と TypeScript 向けのフルスタック開発フレームワークです。データベーススキーマを定義するだけで、フロントエンドとバックエンドの実装を自動的に生成できます。 ZenStack は、Prisma ORM をベースとして構築されているので、Prisma のすべての機能を利用できます。
ZenStack を使用したデータベーススキーマの書き方
ZenStack では、ZModel というデータモデリング言語でデータベーススキーマを作成します。 Prisma Schema をベースとしているので、基本的な文法は Prisma Schema と同じように書くことができます。
また、VSCode 向けにZenStack の拡張機能が用意されています。 エラーチェックやコード補完をしてくれるので、ZModel でデータベーススキーマを書く際はインストールしておくと便利です。
ZModel を Prisma Schema に変換する方法
ZModel で定義したデータベーススキーマを Prisma で使用するには、以下のコマンドで ZModel → Prisma Schema に変換する必要があります。
1npx zenstack generate
変換元と変換先のファイルパスを指定したい場合は package.json に以下の設定を記述します。
1 "zenstack": { 2 "schema": "[変換元のZModelファイル(デフォルト:./schema.zmodel)]" 3 "prisma": "[変換先のSchemaファイル(デフォルト:./prisma/schema.prisma)]", 4 },
ZModel の便利機能
Zmodel で利用できる便利な機能をいくつか紹介します。
abstract
ベースとなる抽象化 model を作成し、各項目を継承できます。 登録日時などのように、各テーブルに共通なフィールドがある場合に使うと便利です。
1generator client { 2 provider = "prisma-client-js" 3} 4 5datasource db { 6 provider = "postgresql" 7 url = env("DATABASE_URL") 8} 9 10abstract model Base { 11 id Int @id @default(autoincrement()) 12 createdAt DateTime @default(now()) 13 updatedAt DateTime @updatedAt 14} 15 16model User extends Base { 17 email String @unique 18 name String 19 posts Post[] 20} 21 22model Post extends Base { 23 title String 24 content String? 25 published Boolean @default(false) 26 author User? @relation(fields: [authorId], references: [id]) 27 authorId Int? 28}
上記 ZModel を変換すると、以下のような Prisma Schema が生成されます。
1datasource db { 2 provider = "postgresql" 3 url = env("DATABASE_URL") 4} 5 6generator client { 7 provider = "prisma-client-js" 8} 9 10model User { 11 id Int @id() @default(autoincrement()) 12 createdAt DateTime @default(now()) 13 updatedAt DateTime @updatedAt() 14 email String @unique() 15 name String 16 posts Post[] 17} 18 19model Post { 20 id Int @id() @default(autoincrement()) 21 createdAt DateTime @default(now()) 22 updatedAt DateTime @updatedAt() 23 title String 24 content String? 25 published Boolean @default(false) 26 author User? @relation(fields: [authorId], references: [id]) 27 authorId Int? 28}
ファイル分割
1 ファイルで全てのスキーマを定義すると、スキーマが増えてくるにつれて管理が大変になると思います。 そこで、ZModel ファイルを分割してスキーマ定義する方法を紹介します。
今回の例では ZModel ファイルを以下のように分割してみます。
- base.zmodel: generator や datasource を記述するファイル
- user.zmodel: user のスキーマ
- post.zmodel: post のスキーマ
base.zmodel
1// importに分割したZmodelファイルをすべて記載します 2import "user" 3import "post" 4 5generator client { 6 provider = "prisma-client-js" 7} 8 9datasource db { 10 provider = "postgresql" 11 url = env("DATABASE_URL") 12}
user.zmodel
1model User { 2 id Int @id() @default(autoincrement()) 3 createdAt DateTime @default(now()) 4 updatedAt DateTime @updatedAt() 5 email String @unique() 6 name String 7 posts Post[] 8}
post.zmodel
1model Post { 2 id Int @id() @default(autoincrement()) 3 createdAt DateTime @default(now()) 4 updatedAt DateTime @updatedAt() 5 title String 6 content String? 7 published Boolean @default(false) 8 author User? @relation(fields: [authorId], references: [id]) 9 authorId Int? 10}
変換元のファイルを「base.zmodel」に指定して変換すると、以下のような Prisma Schema が生成されます。
1datasource db { 2 provider = "postgresql" 3 url = env("DATABASE_URL") 4} 5 6generator client { 7 provider = "prisma-client-js" 8} 9 10model User { 11 id Int @id() @default(autoincrement()) 12 createdAt DateTime @default(now()) 13 updatedAt DateTime @updatedAt() 14 email String @unique() 15 name String 16 posts Post[] 17} 18 19model Post { 20 id Int @id() @default(autoincrement()) 21 createdAt DateTime @default(now()) 22 updatedAt DateTime @updatedAt() 23 title String 24 content String? 25 published Boolean @default(false) 26 author User? @relation(fields: [authorId], references: [id]) 27 authorId Int? 28}
属性
ZModel でのみ使用できる属性を一部紹介します。 詳しい内容は公式リファレンスをご確認ください。
@password
データベースにハッシュ化した文字列を登録/更新します。 内部的にはbcryptjsライブラリを使用してハッシュ化しているようです。
以下のように引数が定義されていて、saltLength からハッシュのコストを設定したり、salt の設定も可能です。
1@password(saltLength: Int?, salt: String?)
@omit
この属性を指定したフィールドはデータ呼び出し時に値が取得されなくなります。 上記の@password と組み合わせて使用すると便利です。
まとめ
最近リリースされたばかりのフレームワークだからなのか、情報量が少なく調べるのに苦労しました。 今回は ZModel を重点的に紹介しましたが、他にも魅力的な機能がたくさんあるライブラリなので、次の機会に紹介したいと思います!
参考
Author Profile
AIROU
プログラマーです 猫とラーメンが好きです
SHARE