ROBOT PAYMENT Engineers Blog

株式会社ROBOT PAYMENTのテックブログです

NestJS を使って最速リリースを目指している話

こんにちは。ROBOT PAYMENTでエンジニアをやっております 牧野です。
今回は新規プロダクトの立ち上げに伴い開発言語からインフラ設計まで0→1でサービスリリースするのに必要な技術選定を行いました。
その際の選定理由や、実際に開発を進めていて得た所感などを書いてみたいと思います。
私は主にバックエンド(フロントエンド以外)を中心に技術選定を行っためそちらを中心に書かせていただきます。

チーム規模

  • バックエンドエンジニア2人
  • フロントエンドエンジニア1人
  • PM 1人
  • デザイナー1人

上記を1チームとして最短距離でリリースすべくスクラム開発を行なっています。
既存の請求管理ロボ開発においては、厳密ではないですがコンテナ運用や監視ツール、CICDなど機能開発以外に関してはSREチームが主に担当しており役割分担しています。

今回は1からサービスリリースするプロダクトということもあり、従来SREチームに依存していた内容含め自ら設計構築を行い、担当領域を決めず自チーム内で包括的にトラブルシューティングできるように開発を進めていることが、今回のプロジェクトの大きなポイントだと思っています。

選定技術

TypeScript

フロントエンド(React.js)、バックエンド(Node.js)にてTypeScriptを採用
後述しますが主にインフラ部分はAWSを利用しており、AWS CDKを利用しコード管理する(Iac)ことでインフラ含め全ての開発言語をTypeScriptに統一しています。

共通の開発言語にすることでフロントバックエンド関係なく相互にレビューしたり、ペアプロ的に開発を進めたり、メリットはかなり大きかったと思っています。
また、静的型付け言語なのでビルド時に早い段階でエラーに気づけるという点もメリットと感じています。

NestJS

バックエンドのフレームワークとしてはNestJSを採用
TypeScript での記述をサポートしているNode.jsフレームワーク かつ 新しすぎず古すぎずを軸に選定しました。
比較対象になるExpressFastifyについては、NestJS内部の実行エンジンで利用しているためあえて選択しておりません。
また、コマンド1発でフロントSPA + RESTサーバー + ORMの環境構築できるfrourioというフレームワークも開発速度という観点で有力候補でしたが、バージョンがv0.2ということもあり採用を見送っています。
余談ですがフロントも含めて管理できるので個人的には使ってみたいフレームワークではあります。あとロゴが可愛いです笑
frourio.com NestJSについては選定段階でAPIや、マイグレ環境など簡単に構築できそうという肌感はありまして、実際かなり簡単に構築できたと思っています。

  • Entityを定義するだけで接続先のDBのカラム定義を自動検知してマイグレファイルの作成まで実施
  • コードベース(Typescript)でGraphQLスキーマ定義が自動生成される

この辺りはかなり開発速度を上げることに繋がりました。
あとはデコレータで簡単にバリデーション実装できたり、moduleでDIを実装できたり便利なことはたくさんありますが、何より公式ドキュメントが充実していて、調べたら大概のことは記載してあったので非常に助かりました。 docs.nestjs.com
一方でNestJSがサポートしているTypeORMを使ったDBアクセスの実装がまだ慣れていないので、ちょっと複雑なクエリを実装しようとした時に直SQLならすぐ書けるのにと思ってしまうことがあり日々学習中です。

GraphQL

フロントエンドと連携するためのAPIについてはGraphQLを採用
REST APIと比較してGraphQLを採用する一般的なメリットを踏まえて選定しました。

  • 単一のエンドポイント
  • 型安全に処理できる
  • Schemaが仕様書代わりになる
  • リクエスト側で必要なデータのみを指定して取得できるなど

GraphQL
POST https:// xxxxxxxxxxxxx/graphql

query{
  books{
    id,
    title,
    price
  },
  users{
    id,
    name,
  shops{
    name,
    address
}

REST API

GET https:// xxxxxxxxxxxxx/books
GET https:// xxxxxxxxxxxxx/users
GET https:// xxxxxxxxxxxxx/shops

例えば上記のようなパターンだと、REST APIは3回に対してGraphQLリクエスト回数は一回で済むのでリクエスト側にメリットがあります。
型含め自動出力されるSchemaをベースにリクエスト側とすり合わせができるのでスムーズに連携できたと思っています。

GraphQLレスポンス例

PostgreSQL

データベースにはPostgreSQLを採用
要件上データの整合性が重要になるケースが多く、検索性も加味した上でRDBを選択しました。
PostgreSQLにはRow Level Securityというデータ行アクセスに対して制限を実装することで、アプリケーション側でなくDB側で権限制御を行う仕組みがあります。
where区に条件を入れ忘れることで意図していないデータまで取得してしまう事象を防げるという観点で利用したいと思い選定しましたが、まだうまく適用できておらずこちらについては今後の課題です。

AWS App Runner

コンテナ上で開発を進めているためECS×Fargateのアーキテクチャ設計で考えておりましたが、直近VPCリソースへのアクセスが可能になったためよりマネージドなAWSサービスを利用したいと考えAWS App Runnerを採用しています。
docs.aws.amazon.com
この辺りはコンテナかサーバーレス(Lambda)で運用するか議論した点もあり、検討したAWSアーキテクチャ関係は別途記事にてまとめたいと思います。

まとめ

今回自チーム内で全て開発し素早くリリースすることをテーマに置いて技術選定をしているためこのような選定結果になりました。開発言語をTypeScriptに統一した点と、NestJSを採用した点はかなり開発スピードを上げる結果に繋がったと思っています!
今後は実装を更に進めた上で、課題感があればその解決方法も踏まえて記事投稿していきたいです。また、AWS関係やCICDなどまだまだ書き足りない部分があるのでそちらは別記事にてまとめる予定です!