STERFIELD

ZenStack を使用してデータベーススキーマを作成する

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

合わせて読みたい