share facebook facebook twitter menu hatena pocket slack

2019.02.25 MON

TypeScript + Serverless + ORM + RoutingMiddlewareを探す旅

高橋 慎一

WRITTEN BY 高橋 慎一

こちらの続きです。

結論

このあたりをうまく組みあわせるとそこそこ楽ちんだった

僕のわがまま

1 .Requestの検証をしたい
2. ドメイン駆動的にEntityを中心とした設計をしたい
3. ローカル開発をDockerで、Deployはserverlessでやりたい
4. DBは案件に応じて柔軟に変更できるようにしたい
5.(後から出てきたけど)webpackもうやだ。消したい

今回はDynamoDB編として紹介します

1. Requestの検証をしたい

nestのこのへんの仕組みclass-validatorで無事解決。
書いておくだけで勝手に検証してくれて適切なエラーを返してくれるのでチョー楽。

UserController.ts

@Put(':id')
@HttpCode(200)
async update(@Param() params: IdRequest, @Body() body: AddUserRequest) {
  await this.repository.save({...params, ...body});
}

2. ドメイン駆動的にEntityを中心とした設計をしたい

勝手にEntityつくればおk
1. と同様にclass-validatorのおかげでだいぶ楽
簡単に扱えるようにBaseEntityを生やした。

BaseEntity.ts

abstract class BaseEntity {
  async validate(): Promise<void> {
    const errors = await validate(this);

    if (errors.length > 0) {
      throw new BadRequestException(errors.toString());
    }
  }
}

User.ts

class User extends BaseEntity {
  @IsNotEmpty()
  id: string;
}

3. ローカル開発をDockerで、Deployはserverlessでやりたい

これも勝手にやれって感じなんだけど、DynamoDBはdynamodb-localなdocker imageが公開されてるのでそれを利用しました。
serverless.ymlは適宜いい感じに!

docker-compose.yml

version: '3'
services:
  user-db:
    image: amazon/dynamodb-local
    ports:
      - 8000:8000
  user-app:
    build: .
    command: npm run start:dev
    volumes:
      - .:/app
      - /app/node_modules
    ports:
      - 3000:3000
    depends_on:
      - user-db

Dockerfile

FROM node:8-alpine

RUN mkdir /app

WORKDIR /app

RUN npm install -g serverless

COPY package*.json ./

RUN set -x \
    && npm install

デプロイするときはこんだけ

deploy

$ docker-compose run --rm --no-deps user-app serverless deploy

4. DBは案件に応じて柔軟に変更できるようにしたい

以前はTypeORMマジヤベー!ブクロサイコー!ってノリでTypeORMばっか使ってたんですが、今回DynamoDB使いたかったのでDynamoDB Data Mapperってのを使いました。
そこそこ使いやすくてよい。

そうじゃない場合 === TypeORMを使って済む場合はnestの公式docを参考にやればおkっぽい。
これはまだ試してないけど問題ないっしょ!!

5. (後から出てきたけど)webpackもうやだ。消したい

nestのValidationPipeなるものを使って 1. を実現するんだけど、serverless-webpack/offlineな環境だとどうしてもCannot find module 'class-validator'. が発生して解決不能に。
nestのissueを見ても解決せず、でもなんとなくwebpackが悪いっぽいってところまで到達。
いろいろwebpackを騙そうとしたけど、最終的にはwebpackやめました。そしてwebpackを徐々に嫌いになっていっている自分に気づきました。

ローカル開発のときはnodemon、デプロイのときはserverless-plugin-typescriptを使うことで解決できそうってところまで調査して、webpack関連を全部消しました。

まとめ

TypeScriptっていうかJavaScriptっていうかその界隈は、フロントエンドな人たちもサーバーサイドな人たちも使っているせいかライブラリがかなり充実してるため、選択肢が数々ありながら最適なものを組み合わせて使うキメラフレームワークみたいな使い方がやりやすいなあっておもいましたあ!
ちょうどフロントはAngular、アプリはionicだったのでnestは違和感なく使えたのもなかなか面白いところですね。

元記事はこちら

TypeScript + Serverless + ORM + RoutingMiddlewareを探す旅

高橋 慎一

高橋 慎一

最強。敗北を知らない。

cloudpack

cloudpackは、Amazon EC2やAmazon S3をはじめとするAWSの各種プロダクトを利用する際の、導入・設計から運用保守を含んだフルマネージドのサービスを提供し、バックアップや24時間365日の監視/障害対応、技術的な問い合わせに対するサポートなどを行っております。
AWS上のインフラ構築およびAWSを活用したシステム開発など、案件のご相談はcloudpack.jpよりご連絡ください。