こちらの続きです。
結論
このあたりをうまく組みあわせるとそこそこ楽ちんだった
僕のわがまま
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つくればおk1.
と同様に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は違和感なく使えたのもなかなか面白いところですね。