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 に変換する必要があります。
npx zenstack generate
変換元と変換先のファイルパスを指定したい場合は package.json に以下の設定を記述します。
"zenstack": {
"schema": "[変換元のZModelファイル(デフォルト:./schema.zmodel)]"
"prisma": "[変換先のSchemaファイル(デフォルト:./prisma/schema.prisma)]",
},
ZModel の便利機能
Zmodel で利用できる便利な機能をいくつか紹介します。
abstract
ベースとなる抽象化 model を作成し、各項目を継承できます。 登録日時などのように、各テーブルに共通なフィールドがある場合に使うと便利です。
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
abstract model Base {
id Int @id @default(autoincrement())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model User extends Base {
email String @unique
name String
posts Post[]
}
model Post extends Base {
title String
content String?
published Boolean @default(false)
author User? @relation(fields: [authorId], references: [id])
authorId Int?
}
上記 ZModel を変換すると、以下のような Prisma Schema が生成されます。
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
generator client {
provider = "prisma-client-js"
}
model User {
id Int @id() @default(autoincrement())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt()
email String @unique()
name String
posts Post[]
}
model Post {
id Int @id() @default(autoincrement())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt()
title String
content String?
published Boolean @default(false)
author User? @relation(fields: [authorId], references: [id])
authorId Int?
}
ファイル分割
1 ファイルで全てのスキーマを定義すると、スキーマが増えてくるにつれて管理が大変になると思います。 そこで、ZModel ファイルを分割してスキーマ定義する方法を紹介します。
今回の例では ZModel ファイルを以下のように分割してみます。
- base.zmodel: generator や datasource を記述するファイル
- user.zmodel: user のスキーマ
- post.zmodel: post のスキーマ
base.zmodel
// importに分割したZmodelファイルをすべて記載します
import "user"
import "post"
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
user.zmodel
model User {
id Int @id() @default(autoincrement())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt()
email String @unique()
name String
posts Post[]
}
post.zmodel
model Post {
id Int @id() @default(autoincrement())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt()
title String
content String?
published Boolean @default(false)
author User? @relation(fields: [authorId], references: [id])
authorId Int?
}
変換元のファイルを「base.zmodel」に指定して変換すると、以下のような Prisma Schema が生成されます。
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
generator client {
provider = "prisma-client-js"
}
model User {
id Int @id() @default(autoincrement())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt()
email String @unique()
name String
posts Post[]
}
model Post {
id Int @id() @default(autoincrement())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt()
title String
content String?
published Boolean @default(false)
author User? @relation(fields: [authorId], references: [id])
authorId Int?
}
属性
ZModel でのみ使用できる属性を一部紹介します。 詳しい内容は公式リファレンスをご確認ください。
@password
データベースにハッシュ化した文字列を登録/更新します。 内部的にはbcryptjsライブラリを使用してハッシュ化しているようです。
以下のように引数が定義されていて、saltLength からハッシュのコストを設定したり、salt の設定も可能です。
@password(saltLength: Int?, salt: String?)
@omit
この属性を指定したフィールドはデータ呼び出し時に値が取得されなくなります。 上記の@password と組み合わせて使用すると便利です。
まとめ
最近リリースされたばかりのフレームワークだからなのか、情報量が少なく調べるのに苦労しました。 今回は ZModel を重点的に紹介しましたが、他にも魅力的な機能がたくさんあるライブラリなので、次の機会に紹介したいと思います!
参考
Author Profile
AIROU
プログラマーです 猫とラーメンが好きです
SHARE