2023年1月6日 更新

Prismaを使ってみた

Prismaはオープンソースのオブジェクト関係マッピング(以降ORM)です。  
「フロントエンドもバックエンドも同じ言語(JavaScript / TypeScript)で実装したい」、「データベースには不慣れだが検証用に簡易的にAPIを実装したい」といったニーズに応えてくれるツールだと考えています。本稿ではPrismaの機能や使い方を簡易的に紹介します。

ORMとは

" O/Rマッピングとは、オブジェクト指向プログラミング言語におけるオブジェクトとリレーショナルデータベース(RDB)の間でデータ形式の相互変換を行うこと。そのための機能やソフトウェアを「O/Rマッパー」(O/R mapper)という。"
via IT 用語辞典 e-Words

ORMは上記のとおり定義されていますが簡単に言うと、プログラミング言語のオブジェクトで定義したメソッドで、SQLを書かずにデータベースの操作が可能なツールということです。 データベースの作成やマイグレーションといった操作や管理を仲介する役割を持っています。

Prismaとは

PrismaはNode.jsを対象としたORMです。  
型安全なデータベースアクセスが特徴でTypeScriptとの相性が良いです。  
Prismaを構成するモジュールは以下の3つです。  

Prisma Client
Node.js, TypeScriptのための、データに合わせて自動生成される型安全なクエリビルダー。メソッドでデータベースを操作するための機能

Prisma Migrate
マイグレーションシステム。設定ファイル(schema.prisma)に基づき実行される

Prisma Studio
データベースを操作するためのGUI
また、様々なデータベース、フレームワーク・ライブラリとの連携が可能です。  

データベース
- PostgreSQL
- MySQL
- SQLite
- MongoDB
- etc...

フレームワーク・ライブラリ
- Next.js
- Nest.js
- Apollo
- GraphQL
- Express
他ORMとの比較
SequelizeやTypeORMが同じNode.jsのORMとして比較されることが多いです。

詳細な比較は以下を参照ください。
- Comparing Prisma / Sequelize  
- Comparing Prisma / TypeORM

私自身Sequelizeしか使用したことがないので、以下はSequelizeを使用した際に不便に感じた点です。  

- Sequlize + TypeScriptの組み合わせで実装すると、TypeScript対応のための追加モジュールが必要になり、記述も冗長になる  
- データ取得の際の条件指定も専用の比較演算子を使用する必要があり、慣れが必要

Prismaは上記の問題がありませんでした。  
特に、TypeScriptを使用する際に特別な設定・記述をする必要がなく、強力な型サポートを受けることができます。  
Prismaは後発のツールのため、SequelizeやTypeORMのいいとこ取りになっており今後シェアが伸びると予想されます。

過去1年のダウンロード数  出典: npm trends

Prismaの使い方

今回はReact・Express・MySQL・Prismaの構成でCRUD操作ができる簡易的な書籍アプリを作成したので、こちらを例に説明します。  
※ React、Express、MySQLのインストールや詳細設定については省略します。

参考資料1:React / Express で作る Web アプリケーション開発入門
参考資料2:Easy Database Access in Express servers

手順は以下のとおりです。  

1. Prismaのインストール
2. schema.prismaの設定
3. マイグレーション
4. APIの実装(Express)
5. Prisma studioの起動

prismaのインストール
以下のコマンドを実行します。


yarn add @prisma/client


.

schema.prismaの設定
Prismaをインストールするとprismaディレクトリ内にschema.prismaが作成されるので、必要な設定を追加します。

generator client​
prisma generateコマンドの対象を設定します。ファイルの内容を更新してマイグレーションをした際に実行されます。

datasource db
使用するデータベースの情報を設定します。urlは環境変数(env)を使用します。

model books
データモデルを設定します。modelの後にテーブル名、フィールド・データタイプ、オプションを設定します。@defaultはデフォルト値を設定可能です。


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

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

model books {
id Int @id @default(autoincrement())
title String
author String
overview String
created_at DateTime @default(now())
updated_at DateTime @default(now())
}


schema.prisma

マイグレーション
以下のコマンドを実行します。


npx prisma migrate dev --name init


.

マイグレーションが完了したら、APIを実装しPrisma Clientを通じてデータベースにアクセスできるようにします。

APIの実装
Expressのルーティングにエンドポイントを追加します。  
PrismaClientをインスタンス化して使用し、各クエリを発行します。  
クエリの結果はすべて完全に型付けされます(ここが素晴らしい!)。


import express, { Request, Response } from "express";
import { PrismaClient } from "@prisma/client";

const router = express.Router();

const prisma = new PrismaClient();

router.get("/", async (_req: Request, res: Response) => {
const readPost = await prisma.books.findMany();
res.json(readPost);
});

router.post("/", async (req: Request, res: Response) => {
const data = { data: req.body };
const createPost = await prisma.books.create(data);
res.json(createPost);
});

router.put("/", async (req: Request, res: Response) => {
const updatePost = await prisma.books.update({
where: { id: req.body.id },
data: req.body,
});
res.json(updatePost);
});

router.delete("/", async (req: Request, res: Response) => {
const deletePost = await prisma.books.delete({ where: { id: req.body.id } });
res.json(deletePost);
});

module.exports = router;


books.ts

Prisma studioの起動
以下のコマンドを実行すると、Prisma studioというデータベースを操作するためのGUI(localhost:5555)が起動します。


npx prisma studio


.

まとめ

Prismaは機能や記述がシンプルなので使いやすく、TypeScripとの相性の良さという点でも積極的に使いたくなるツールでした。  

また、冒頭でも述べましたが「フロントエンドもバックエンドも同じ言語(JavaScript / TypeScript)で実装したい」、「データベースには不慣れだが検証用に手軽にAPIを実装したい」とニーズに応えてくれるのでおすすめしたいです。    

今回は簡易的な部分しか触れませんでしたが、他の機能も試して研究を続ける予定です。  
今後はNest.jsやGrapQLとの組み合わせも試し、様々な組み合わせのナレッジをお伝えしていきたいと思います。

参考資料
Prisma
Prisma: Node.js & TypeScript向けの完璧なORM
Node.js(Express.js)環境でPrisma ORMを使いこなすための基礎

※掲載内容は個人の見解です。
※会社名、製品名、サービス名等は、各社の登録商標または商標です。