NestJSにおけるルーティングに関するお勉強記録です。主に以下のページを見て学んだ内容になります。
Controllers | NestJS - A progressive Node.js framework
ルーティング
Laravelだとroutes/web.phpファイルとかにルーティング情報を書き加えていく訳ですが、NestJSの場合はControllerのファイルにデコレータというものを使って記述していくようです。
コントローラーの作成
NestJSでは以下のコマンドでコントローラーを作成できます。
nest g controller cats
上記コマンドを実行するとsrcフォルダの下にcatsというフォルダが作成され、その中に以下のファイルが作成されていることが確認できます。中身を見た感じcats.controller.spec.tsファイルの方はテスト用のファイルかなと思いますが現時点ではよく分かりません。もう片方のcats.controller.tsがコントローラーのファイルのようです。
- cats.controller.spec.ts
- cats.controller.ts
また、app.module.tsファイルに対して、作成したコントローラも登録してくれています。
ルートの作成
Get用のルート作成
cats.controller.tsファイルを以下のように編集します。
1 2 3 4 5 6 7 8 9 |
import { Controller, Get } from '@nestjs/common'; @Controller('cats') export class CatsController { @Get() findAll(): string { return 'This action returns all cats'; } } |
CatsControllerというクラスに@Controller('cats')というデコレータをセットしています。また、findAllというメソッドに@Get()というデコレータをセットしています。こうすることでhttp://localhost:8000/catsにGetでアクセスすると、このメソッドが呼ばれ、returnした文字列が返る形になります。
@Get()デコレータを@Get('hoge')のように指定するとhttp://localhost:8000/cats/hogeというルートが作成されます。findAll()というメソッド名には意味は無く、どんなメソッド名でも構いません。
例えばこんなコードでも動きます。
1 2 3 4 5 6 7 8 9 |
import { Controller, Get } from '@nestjs/common'; @Controller('cats') export class CatsController { @Get('hoge') fuga(): string { return 'piyo'; } } |
以下の様な結果になります。
補足
returnで配列やオブジェクトを渡すと自動的にシリアライズして返してくれるそうです。例えばこんなコードでもOKとのことでした。
1 2 3 4 5 6 7 8 9 |
import { Controller, Get } from '@nestjs/common'; @Controller('cats') export class CatsController { @Get('hoge') fuga(): object { return { piyo: 0 }; } } |
以下の様な結果になります。
このような形以外の返し方も書いてありましたが、自分はあまり使わなさそうなので割愛します。
リクエストオブジェクト
リクエストオブジェクトの取得
リクエストオブジェクトを取得するのもデコレータを使うそうです。
1 2 3 4 5 6 7 8 9 10 |
import { Controller, Get, Req } from '@nestjs/common'; import { Request } from 'express'; @Controller('cats') export class CatsController { @Get() findAll(@Req() request: Request): object { return request.query; } } |
以下の様な結果になります。
クエリーパラメータの取得
リクエストオブジェクトを使わず、クエリーパラメータをデコレーターで取得する場合のサンプルです。
1 2 3 4 5 6 7 8 9 |
import { Controller, Get, Query } from '@nestjs/common'; @Controller('cats') export class CatsController { @Get() findAll(@Query('name') name: string): string { return name; } } |
以下の様な結果になります。
パスパラメータの取得
リクエストオブジェクトを使わずパスパラメータをデコレーターで取得する場合のサンプルです。Laravelだとパスで{name}のように{}で括ってたけどNestJSは:nameの様に:を付けます。
1 2 3 4 5 6 7 8 9 |
import { Controller, Get, Param } from '@nestjs/common'; @Controller('cats') export class CatsController { @Get(':name') findAll(@Param('name') name: string): string { return name; } } |
以下の様な結果になります。
ペイロードの取得
ペイロードの取得にはDTOスキーマ(Data Transfer Object)というのを用意するのがお作法のようです。catsフォルダの下にdtoというフォルダを作り、「create-cat.dto.ts」という名前でファイルを作り、以下のように編集します。
1 2 3 4 5 |
export class CreateCatDto { name: string; age: number; breed: string; } |
以下のサンプルコードの様にPost用のメソッドを用意します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
import { Controller, Get, Post, Body, Param } from '@nestjs/common'; import { CreateCatDto } from './dto/create-cat.dto'; @Controller('cats') export class CatsController { @Get(':name') async findAll(@Param('name') name: string): Promise<string> { return name; } @Post() create(@Body() createCatDto: CreateCatDto): string { return createCatDto.name; } } |
curlで以下の様にPostしてみるとhogeと返ってきます。Windowsで試しているので"を\でエスケープしています。ちなみにバリデーションしてくれる訳ではないのでageに数字以外をしていてもエラーになったりはしませんでした。
curl -X POST -H "Content-Type: application/json" -d "{\"name\":\"hoge\", \"age\":3}" http://localhost:8001/cats
その他
ステータスコードやヘッダー、リダイレクトなんかをいじる方法も書かれてましたが割愛します。最後の状態のコードを一応置いておきます。