Open2
Nest.jsについて
DTO
DTOとは (Data Transfer Object)
- データの受け渡しに使われるオブジェクト
- DBとモデルクラス間のデータのやり取りやリクエストオブジェクトからのデータ受け取りなどで使用される
メリット
- メンテナンス性が高まる
- アプリの安全性が高まる。誤ったデータの型が扱われるリスクが減る
- Nest.jsのバリデーション機能が使える
DTOを使ったコードのリファクタ
POSTメソッドのリファクタリングを行う
createMovieDto
クラスを宣言します
create-movie.dto.ts
export class CreateMovieDto {
id: number;
title: string;
description: string;
rating: number;
review: string;
}
最初の実装では各プロパティを個別の@Bodyデコレータで受け取っていた。
この方法だとコードが冗長になる。
またプロパティを追加するときのコードの変更箇所が多い。
movies.controller.ts(リファクタ前)
@Post()
create(
@Body('id') id: number,
@Body('title') title: string,
@Body('description') description: string,
@Body('rating') rating: number,
@Body('review') review: string,
): Movie {
const movie: Movie = {
id: id,
title,
description,
rating,
review,
};
return this.moviesService.create(movie);
}
CreateMovideDtoというDTOを導入することで、一つの@Body
デコレータでリクエストボディ全体を一つのオブジェクトとして受け取ることができ、コードがシンプルに!
プロパティを追加する際はDTOのプロパティだけ変更すればOK
一つの@Body
で受け取るには、DTOとボディパラメータのプロパティが等しくないといけない
movies.controller.ts(リファクタ後)
import { CreateMovieDto } from './DTO/create-movie.dto';
// ~~~~~省略~~~~~
@Post()
create(@Body() createMovieDto: CreateMovieDto): Movie {
return this.moviesService.create(createMovieDto);
}
コントローラからサービスへcreateMovieDto
が渡されるようになるため、 サービスのメソッドの引数をcreateMovieDto
に変更。
...createMovieDto
でオブジェクトを展開してmovie
変数にコピー。(スプレッド構文を用いたES6の記述)
スプレッド構文を使うことで、将来プロパティが増えても自動で展開されるため変更が不要。
DTOスプレッド構文を使って展開。
movies.service.ts
create(createMovieDto: CreateMovieDto): Movie {
const movie: Movie = {
...createMovieDto,
};
this.movies.push(movie);
return movie;
}
以下の場合は、プロパティが増えた場合手動で追加しないといけない。
movies.service.ts (スプレッド構文を使わない場合)
const movie: Movie = {
id: createMovieDto.id,
title: createMovieDto.title,
description: createMovieDto.description,
rating: createMovieDto.rating,
review: createMovieDto.review
};