前置き
- 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()) { // 処理 }