はじめに
30代未経験からエンジニアを目指して勉強中のYNと申します。
TypeScriptを勉強しているなか、NestJSというフレームワークにたどり着きました。これから長い付き合いになりそうです。
学んだことをメモとして書きます。
プロジェクトを始める
npm i -g @nestjs/cli #グローバルインストール
nest new <project-name> #プロジェクト作成
yarn start:dev #サーバー起動
// もしグローバルインストールをしない場合↓
// yarn add -D @nestjs/cli @nestjs/schematics
// npx nest new <project-name>
基本構造
プロジェクトを作成すると、module
controller
service
が作られる。
それそれの役割は公式ドキュメントが分かりやすいが、下図が自分の理解。
-
module
: 一つのAPI。リクエストを受け取る。 -
controller
: routerとして機能。moduleに届いたリクエストを各エンドポイントごとに処理する -
service
: 実際の処理を記述する
$nest new <project-name>
直後の構造はこんな感じ
CLIコマンド
module
controller
service
などのコンポーネントの雛形はCLIで作ることができる。公式ドキュメント参照。
nest g <schematic> <name> [options]
Pipe
Pipe
はリクエストの内容をvalidate
したりtransform
したりできる。module
・controller
・service
に届く前のいずれかの場所に実装できる。
あたらしくControllerを実装する
CLIでcontrollerとserviceを追加
自動的にsrc/cats
フォルダにcontrollerとserviceを作ってくれる。
nest g controller cats
nest g service cats
また、app.module.ts
にcontrollerが追加されていることがわかる。
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { CatsController } from './cats/cats.controller';
import { CatsService } from './cats/cats.service';
@Module({
imports: [],
controllers: [AppController, CatsController], //ここにcontrollerが自動で追加されている
providers: [AppService, CatsService],
})
export class AppModule {}
Cat interfaceの定義
データとして保持するためのCatの型を定義する。
export interface Cat {
name: string;
age: number;
breed: string;
}
Cat DTOの定義
リクエストbodyで送られてくる情報を規定する。
interfaceではなく、class表現をつかうことで、validationのためのデコレーターを使うことができる。
これと前述のPipeを組み合わせて、リクエストのvalidationが可能となる。
import { IsString, IsInt } from 'class-validator';
export class CreateCatDto {
@IsString()
name: string;
@IsInt()
age: number;
@IsString()
breed: string;
}
controllerの記述
controllerでvalidationを行う場合、@UsePipes(new ValidationPipe())
で行う。
ValidationPipe
の中身についてはこちらを参照させていただくと分かりやすい。
import {
Controller,
Get,
Post,
Body,
ValidationPipe,
UsePipes,
} from '@nestjs/common';
import { CreateCatDto } from './dto/create-cat.dto';
import { CatsService } from './cats.service';
import { Cat } from './interfaces/cat.interface';
@Controller('cats')
@UsePipes(new ValidationPipe({ transform: true })) // ここでvalidationをする
export class CatsController {
constructor(private catsService: CatsService) {}
@Post()
async create(@Body() createCatDto: CreateCatDto) {
this.catsService.create(createCatDto); // serviceを実行
}
@Get()
async findAll(): Promise<Cat[]> {
return this.catsService.findAll(); // serviceを実行
}
}
serviceの記述
import { Injectable } from '@nestjs/common';
import { Cat } from './interfaces/cat.interface';
@Injectable()
export class CatsService {
private readonly cats: Cat[] = [];
create(cat: Cat) {
this.cats.push(cat);
}
findAll(): Cat[] {
return this.cats;
}
}
動作確認
postした後にgetすると登録したcatsが返ってくることがわかる。
ageにnumber以外をpostするとちゃんとエラーが返ってくる
参考にさせていただいたもの
https://youtu.be/HQ3tjl_Sh9s
https://youtu.be/F_oOtaxb0L8
https://qiita.com/taqm/items/4bfd26dfa1f9610128bc