LoginSignup
5
3

More than 5 years have passed since last update.

TypeScriptベースなRequestの共通化

Posted at

前置き

  • 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()) {
    // 処理
}
5
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
3