前置き
- App: ionic
- Web: Angular
- API: Nest.js
僕たちのチームのフレームワーク採用はこんな感じで全部Angularベース。
API Docはapi blueprintあたりを採用。
「でもこれ、フロントエンド/バックエンドで同じような実装するじゃん...無駄じゃね」
と思いはじめて実験的に取り組んでみてる構成を紹介します。
Requestクラスを共通化する
Requestクラスを別リポジトリに分けて、git moduleとして扱っちゃう作戦です。
構成とコマンドは以下のような感じ。
今回はUser追加のリクエストを共通化する例です。
ディレクトリ構成
├── app
│ ├── tsconfig.json
│ ├── package.json
│ └── src
│ └── common (submodule: common)
├── api
│ ├── tsconfig.json
│ ├── package.json
│ └── src
│ └── common (submodule: common)
└── common
├── tsconfig.json
├── package.json
└── Requests
└── AddUserRequest.ts
サブモジュールの追加
$ git submodule add ./src/common
$ npm i ./src/common
RequestClass
class-validatorにしたがって以下のようにすると楽ちんです。
BaseRequest.ts
import { validate } from "class-validator";
export class BaseRequest {
async validate(): Promise<boolean> {
const errors = await validate(this);
if (errors.length > 0) {
throw new Error(errors.toString());
} else {
return true;
}
}
}
AddUserRequest.ts
import * as v from "class-validator"
export class AddUserRequest extends BaseRequest{
@v.IsNotEmpty()
id: string;
@v.IsDate()
@v.IsOptional()
birthday: Date;
}
こうしておくことでNest.js側では通常通りにValidationがかかります。
@Post("/user")
@HttpCode(200)
async create(@Body() params: AddUserRequest) {
// 処理
}
Angularやionic側ではclass-transformerを使ってvalidateが可能です
import { plainToClass } from "class-transformer";
const req: AddUserRequest = plainToClass(request);
if (await req.validate()) {
// 処理
}