ExpressとPrismaでAPIを作ってみた

はじめに

バックエンドでLaravelを使って画面込みでシステムを作ることが多かったのですが、最近はフロントエンドはVue.js、ReactでバックエンドはAPIのみという案件も増えているのでLaravelに拘らなくてもいいかなと思うこともあり、他のフレームワークを探したところ、フロントエンドで使われるNode.jsやTypeScriptに相性の良さそうなExpressとPrismaがあったので使ってみました。
ExpressはNode.jsで動作するWebフレームワークで、PrismaはNode.jsで動作するORMです。

Prismaを入れる

ではまず、Prismaをインストールして、Database環境を作っていきます。
プロジェクトのディレクトリを作成して中で作業します。
$ mkdir api
$ cd api

TypeScriptを初期化します。

$ npm init -y
$ npm install typescript ts-node @types/node --save-dev
$ npx tsc --init
Prismaのセットアップをします。
$ npm install prisma --save-dev
$ npx prisma init --datasource-provider sqlite
実行するとprisma/schema.prismaファイルが作成されます。
SQLiteになっているのが確認できました。
// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema

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

datasource db {
  provider = "sqlite"
  url      = env("DATABASE_URL")
}
次にprisma/schema.prismaファイルへmodelを追加していきます。Userを追加します。
model User {
  id    Int     @id @default(autoincrement())
  email String  @unique
  name  String?
}
マイグレーションを実行します。
$ npx prisma migrate dev --name init
Environment variables loaded from .env
Prisma schema loaded from prisma/schema.prisma
Datasource "db": SQLite database "dev.db" at "file:./dev.db"

Applying migration `20240511142813_init`

The following migration(s) have been created and applied from new schema changes:

migrations/
  └─ 20240511142813_init/
    └─ migration.sql

Your database is now in sync with your schema.

Running generate... (Use --skip-generate to skip the generators)

added 1 package, and audited 28 packages in 6s

found 0 vulnerabilities

✔ Generated Prisma Client (v5.13.0) to ./node_modules/@prisma/client in 69ms
migration.sqlというテーブルを作成するSQLファイルが生成されてました。
-- CreateTable
CREATE TABLE "User" (
    "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
    "email" TEXT NOT NULL,
    "name" TEXT
);

-- CreateIndex
CREATE UNIQUE INDEX "User_email_key" ON "User"("email");
ちなみにその後カラムを追加してマイグレーションを実行した場合は、テーブルとの差分のみのSQLファイルを作成してカラムを変更してくれます!
-- CreateTable
model User {
  id    Int     @id @default(autoincrement())
  email String  @unique
  name  String?
  address  String? // 追加
}
-- AlterTable
ALTER TABLE "User" ADD COLUMN "address" TEXT;
成功したのでUserのテーブルができたはずです。次はUserにレコードを追加します。
PrismaにはGUIでレコードを編集できるツールがあります!便利ですね~
$ npx prisma studio
Userにuser1とuser2を追加しました。
Databaseの準備はできたので、呼び出すAPIをExpressで作成していきます。

Expressを入れる

Expressをインストールします。
$ npm install express
$ npm install -D @types/express
登録したUserを取得するAPIを書いていきます。
PrismaClientを使うことでデータベースの操作ができるようになります。
Userのレコードをすべて取得してレスポンスで返すようにします。
import express from "express";
import { PrismaClient } from "@prisma/client";

const prisma = new PrismaClient();
const app = express();
app.use(express.json());
app.use(express.urlencoded({extended: true }));

app.get('/', async (req, res) => {
    const users = await prisma.user.findMany();
    res.json(users);
})

const PORT = process.env.PORT || 3000;

app.listen(PORT, () => {
    console.log(`Server is running on port ${PORT}`);
});

APIを実行する

nodemonをインストールして書いたAPIが動作するようにpackage.jsonに起動スクリプトのstartを設定します。
$ npm install nodemon --save-dev
"scripts": {
  "start": "nodemon --exec ts-node src/index.ts"
},
expressを起動してcurlでAPIの応答を確認してみます。
curlでAPIにアクセスするとUserに追加したレコードが返ってきました!
$ npm start
> api@1.0.0 start
> nodemon --exec ts-node src/index.ts

[nodemon] 3.1.0
[nodemon] to restart at any time, enter `rs`
[nodemon] watching path(s): *.*
[nodemon] watching extensions: ts,json
[nodemon] starting `ts-node src/index.ts`
Server is running on port 3000
$ curl http://localhost:3000/
[{"id":1,"email":"user1@example.com","name":"user1"},{"id":2,"email":"user2@example.com","name":"user2"}]

おわりに

書くコード量も設定も少なくAPIのサーバーを構築することができました。
今回Prismaは最低限の取得のみで使用しましたがリレーションなど機能も充実しているので扱いやすいと思います。
同じ言語を使用しているのでフロントエンドをメインまたはバックエンドをメインに仕事をしている人も互いに関わりやすいのではないでしょうか。

記事を読んで興味を持った方はぜひコチラから↓