NestJS + PrismaをSwaggerUIでテストする【岸川 彪我 / Hyoga Kishikawa】
自己紹介
はじめまして、岸川と申します。Marvel株式会社でフロントエンドエンジニアとして活動している者です👨💻
メインはフロントエンドですが、バックエンドも問題なく触れます👀
1. はじめに
案件を探す際に「NestJSを触ったことありますか」と聞かれることが多く、当時はNestJSを全く知りませんでしたが、フロントエンドとバックエンドを同じ言語(JavaScript/TypeScript)で作っていけることに魅力を感じています。
2. 環境構築
2-1. 環境
下記環境で構築していきます。
npm
NestJS: v10.0.0
Prisma: v5.5.2
2-2. NestJSインストール
今回はTypeScript製のスタータープロジェクトを使用するので
$ git clone https://github.com/nestjs/typescript-starter.git project
$ cd project
$ npm install
$ npm run start
ブラウザを開き http://localhost:3000 でNestJSが立ち上がります。
2-3. Prismaインストール
$ npm install prisma –save-dev
$ npm install @prisma/client
インストールできたらinitコマンドでPrismaを初期化しましょう。
prismaディレクトリが作られます。
$ npx prisma init
prismaディレクトリ配下のschema.prismaでデータベースの設定を行います。
3. データベース作成
3-1. データベース接続設定
schema.prismaファイルを下記に変更します。
今回はデータベースにsqliteを使用します。
datasource db {
provider = “sqlite”
url = ”file:./dev.db”
}
generator client {
provider = “prisma-client-js”
}
3-2. モデル作成
schema.prisma
model Cat {
id Int @default(autoincrement()) @id
name String
}
3-3. ビジュアルエディターでモデルを確認
$ npm run studio
ブラウザを開き http://localhost:5555 でビジュアルエディターが立ち上がります。
このビジュアルエディターではモデルとデータの確認ができ、データの追加や修正も行えます。
4. API作成
4-1. PrismaService作成
Prismaクライアントのインスタンスを使いまわせるようにInjectableなクラスを作成します。
src/common/prisma.service.ts
import { Injectable, OnModuleInit } from '@nestjs/common';
import { PrismaClient } from '@prisma/client';
@Injectable()
export class PrismaService extends PrismaClient implements OnModuleInit {
async onModuleInit() {
await this.$connect();
}
}
4-2. CatsService作成
Catモデルからデータを取得するクラスを作成します。
src/cats/cats.service.ts
import { Injectable } from '@nestjs/common';
import { PrismaService } from '../common/prisma.service';
import { Cat } from '@prisma/client';
@Injectable()
export class CatsService {
constructor(private prismaService: PrismaService) {}
async cats(): Promise<Cat[]> {
return this.prismaService.cat.findMany();
}
}
4-3. CatsController作成
CatsServiceを使用してルーティングを定義をします。
src/cats/cats.controller.ts
import { Controller, Get } from '@nestjs/common';
import { CatsService } from './cats.service';
import { Cat } from '@prisma/client';
@Controller(‘cats’)
export class CatsController {
constructor(private catsService: CatsService) {}
@Get()
async cats(): Promise<Cat[]> {
return this.catsService.cats();
}
}
4-4. Module登録
CatsルーティングをNestJSに認識させるために、CatsModuleを作成しAppModuleに追加します。
src/cats/cats.module.ts
import { Module } from '@nestjs/common';
import { CatsService } from './cats.service';
import { PrismaService } from '../common/prisma.service';
import { CatsController } from './cats.controller';
@Module({
controllers: [CatsController],
providers: [
CatsService,
PrismaService,
],
})
export class CatsModule {}
src/app.module.ts
import { Module } from '@nestjs/common';
import { CatsModule } from './cats/cats.module';
@Module({
imports: [CatsModule],
})
export class AppModule {}
これでAPIを通してデータを取得までできました。
ビジュアルエディターでcatsモデルにデータを追加し、ブラウザで http://localhost:3000/cats を確認すると登録されているデータが表示されると思います。
5. SwaggerUIでAPIテスト
5-1. Swaggerインストール
$ npm install @nestjs/swagger
5-2. Swaggerの設定
アプリケーションのエントリーポイント(src/main.ts)に設定します。
src/main.ts
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
const config = new DocumentBuilder()
.setTitle('Cats API')
.setDescription('Cats API description')
.setVersion('1.0')
.build();
const document = SwaggerModule.createDocument(app, config);
SwaggerModule.setup('documents', app, document);
await app.listen(3000);
}
bootstrap();
5-3. SwaggerにCatsControllerの情報を記載
Swaggerデコレータを使用してCatsControllerの情報をSwaggerに追加します。
CatsControllerを下記に書き換えます。
src/cats/cats.controller.ts
import { Controller, Get } from '@nestjs/common';
import { CatsService } from './cats.service';
import { Cat } from '@prisma/client';
import {
ApiOperation,
ApiResponse,
ApiTags,
} from '@nestjs/swagger';
@ApiTags('/cats)
@Controller(‘cats’)
export class CatsController {
constructor(private catsService: CatsService) {}
@Get()
@ApiOperation({ summary: 'Cats取得' })
@ApiResponse({
status: 200,
description: 'Catsデータ',
})
async cats(): Promise<Cat[]> {
return this.catsService.cats();
}
}
5-4. APIドキュメントの確認
$ npm run start
ブラウザを開き http://localhost:3000/documents でSwaggerUI APIドキュメントを確認します。
6. 感想
Marvel株式会社初のアドベントカレンダーに参加させていただきました🎄
Qiitaなどの技術サイトでアドベントカレンダーが行われていることは認知していましたが、誰かにちゃんと伝わるように書けるかなという不安で参加せずにいました。ですが、今回Marvelでアドベントカレンダーをやるということで、アウトプットを兼ねて参加いたしました🔥
昨今のフロントエンドはVue/Reactの割合が多い印象で、
Nest.jsではフロントエンドとバックエンドをJavaScriptで一貫して作れる(JavaScript/TypeScriptだけで完結できる)ところがいいなと思いました。