見出し画像

NestJS + PrismaをSwaggerUIでテストする【岸川 彪我 / Hyoga Kishikawa】

自己紹介

はじめまして、岸川と申します。Marvel株式会社でフロントエンドエンジニアとして活動している者です👨‍💻
メインはフロントエンドですが、バックエンドも問題なく触れます👀

1. はじめに

案件を探す際に「NestJSを触ったことありますか」と聞かれることが多く、当時はNestJSを全く知りませんでしたが、フロントエンドとバックエンドを同じ言語(JavaScript/TypeScript)で作っていけることに魅力を感じています。

NestJS

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だけで完結できる)ところがいいなと思いました。

Marvelでは今年『Marvelアドベントカレンダー2023』をやります🎄🎅Marvelのエンジニアがクリスマスまで記事のバトンを繋ぎます🔥
是非毎日のお楽しみとしてご覧ください😊
★Marvelのアドベントカレンダーはこちらhttps://adventar.org/calendars/9781


いいなと思ったら応援しよう!