NestJS への API リプレース体験記

10.2K Views

April 03, 23

スライド概要

References
- https://docs.nestjs.com/graphql/other-features
- https://docs.nestjs.com/graphql/plugins
- https://aws.amazon.com/jp/memorydb/

profile-image

GraphQL | TypeScript | NestJS

シェア

またはPlayer版

埋め込む »CMSなどでJSが使えない場合

関連スライド

各ページのテキスト
1.

NestJS への API リプレース体験記 NestJS meetup Online #5

2.

自己紹介 choco / @choco14t ● 株式会社スペースマーケット (2021-06〜) ○ ● バックエンドエンジニア NestJS、GraphQL 駆け出し (2021-12〜) © Spacemarket, Inc. All Rights Reserved. 2

3.

Agenda 話すこと 話さないこと ● 移行の背景 ● 採用しているライブラリ ○ NestJS について ● 移行時の課題・対応 ○ GraphQL についてなど ● 現状の課題 ● 問題に直面したとき © Spacemarket, Inc. All Rights Reserved. ● 使用技術に関すること 3

4.

移行の背景

5.

移行の背景 ● ● Ruby、Rails のバージョンアップコスト ○ Ruby v2.4.6 ○ Rails v5.1.6.2 リポジトリの乱立 ○ ● API、バッチ合わせると 15 程度 TypeScript 採用による FE との言語統一 © Spacemarket, Inc. All Rights Reserved. 5

6.

採用ライブラリ

7.

採用ライブラリ ● Fastify ● TypeORM ● GraphQL (Code First) ● Apollo Server (Federation) ● Bull (検証段階、後述) © Spacemarket, Inc. All Rights Reserved. 7

8.

移行時の課題・対応

9.

Field Resolver + Guard による DB I/O 増加 ● あるリリースを境に DB I/O が急増 ● Guard と @ResolveField の相性が悪い ● ○ ドキュメント にも記載されている ○ 対象のフィールドが参照されるたびに SQL が実行されていた context を使ってリクエスト時に認証オブジェクトを生成する手法に変えた © Spacemarket, Inc. All Rights Reserved. 9

10.

© Spacemarket, Inc. All Rights Reserved. 10

11.

改修後の結果 ● I/O が激減してアラートもこなくなった ● GraphQL を使っている方は context の利用を検討するといいかも? © Spacemarket, Inc. All Rights Reserved. 11

12.

非同期ジョブの実装 ● Bull を採用 ● Bull のバックグラウンドは Redis ● しかし、自身が Redis にあまり詳しくない... © Spacemarket, Inc. All Rights Reserved. 12

13.

非同期ジョブの実装 - MemoryDB の検証 ● Redis 互換のインメモリデータベース ● データを永続的に保存してくれる 実際に試してみた結果... © Spacemarket, Inc. All Rights Reserved. ● なんとかジョブの登録、実行できるところまではできた ● NestJS のドキュメントに記載されている設定では不十分 ○ Bull のドキュメント ○ ioredis の issue 13

14.

Code First + Federation 特有のバグ ● Apollo Server のキャッシュ機能が使えないか検証するタイミングがあった ● 実際に設定してもキャッシュが効かず、クエリが実行される ● Schema First に変えてみると動作したためバグと判断 ○ ● 最終的に PR を作成した 現時点でもいくつかバグがある ○ 特定の機能が使えないほどのものは観測していない © Spacemarket, Inc. All Rights Reserved. 14

15.

gem に依存した実装 移行前のリポジトリで使用していた gem と代替の実装について ● acts-as-taggable-on ○ ● geocoder ○ ● TypeORM のリレーション定義で実装 実行されているクエリをログから参照して引用 graphql-guard ○ FieldMiddleware を使って実装 © Spacemarket, Inc. All Rights Reserved. 15

16.

Logging ● @Plugin、ApolloServerPlugin を使って実装 ○ ● providers に追加するだけで動作するので楽 gateway 経由で uuid を渡してリクエスト内で実行されたクエリを追いやすく © Spacemarket, Inc. All Rights Reserved. 16

17.

Rails Cache ● デフォルト設定 (LRU) だったので、ひとまず踏襲 ● NestJS が提供している CacheModule を使用 © Spacemarket, Inc. All Rights Reserved. 17

18.

現状の課題

19.

現状の課題 ● @nestjs/cqrs を使った実装 ○ 実装コストに対して旨味が感じられず ○ Resolver + Service + Repository の実装へ ■ ● 初期の実装が残っており実装パターンが乱立している テーブル単位でのモジュール分割になってしまっている ○ テーブル参照増加に比例してモジュール参照も増加 © Spacemarket, Inc. All Rights Reserved. 19

20.

問題に直面したとき

21.

問題に直面したときに... ● ● ● ググる ○ 定番 ○ 検索設定で英語に絞る ○ 日本語だとまだまだ問題解消に対する記事は少ない印象 NestJS コミュニティ ○ 類似した投稿がないか検索する or 質問を投稿する ○ Discord なので検索体験が良いとは言えない GitHub issue ○ Bull、ioredis ○ TypeORM、mysql2 など © Spacemarket, Inc. All Rights Reserved. 21

22.

まとめ ● 色々と言われているが Rails のエコシステムは偉大 ● NestJS、Node.js のエコシステムも偉大 ● 英語のリソースを恐れない © Spacemarket, Inc. All Rights Reserved. 22

23.

ご清聴ありがとうございました