Backendの共通ロジックをnpm packageにして公開

Backendの共通ロジックをnpm packageにして公開

こんにちは、バックエンドエンジニアの山浦、國藤です。

こちらの記事では新しく作ったbackendの共通ロジック npm package @plugoinc/commonについて、

  • 作った経緯
  • 導入の準備
  • 実装
  • 導入
  • 導入後の運用

を紹介できればと思います

作るに至った経緯

現状は、バックエンドの開発がNode.jsがメインで使用されていて、3つあるサーバの開発やcloud functionなどで利用しています。

三つのサーバはすべてNest.jsを使って実装しており、開発進める中で一つのサーバで磨いたノウハウや実装を他のサーバに横展開するのにコピペしていました。しかし、一つのサーバで改修を行うと他のサーバでも同じ修正が必要であり、無駄です。

そこで共通ロジックをまとめたnpm packageを作ることにしました。

導入の準備

Node.jsのバージョンを揃える

まず、common packageを作るにおいて、サポートするNode.jsのバージョンを決める部分から始めました。

サーバ側はNode.js v18をメインで使用していて、一台だけ古いNode.jsを使っていたので、そのNode.jsのバージョンアップを待つ必要がありました。

また、cloud functionで使えるNode.jsのバージョンは複数ありますが、2023年12月現在ではNode.js v18が推奨バージョンになっており、ここも揃っていたので両方で使えるものにできます。

移動する機能を考える

それぞれで共通になっている部分が何かを洗い出す必要がありました。その中でも、まずは以下の二つの機能を入れることにしました。

  • Logger
    • winstonをラッピングしているLogger
      • ログメッセージに加えてデータをjsonなどで出力できるようにしている。
  • Result型
    • Success, Failureを内包、柔軟なエラーを返せる、型でguardできるので便利

実装

実装に関して、OSSとして公開する予定つもりだったので、Plugoでメインで利用しているGitlabではなく、GitHubにアップロードすることにしました。

GitHub

dependabotの導入

依存しているnpm packageのバージョン管理やセキュリティアップデートを素早く反映するために、dependabotを導入しました。設定として、1週間に1回更新するようにしました。

PRの形で変更がくるので、とても便利です。また、PRなのでCIも走り、unit testで動作も確認できるので助かります。

slackのgithubアプリ導入

githubのリポジトリの変更をslackに通知してくれる、githubのアプリがとても便利です。

PRが新しく作られたり、closeされたときにすぐ気づけます。

slack上でレビュー依頼ややり取りをあまり行わなくてもこのbotとgithub上でほとんど完結できるところはDXとしてチーム内からも高評価です。

導入

導入する時には、まず新しく npm i @plugoinc/commonを実行し、既存のResult型の定義、Loggerの定義を削除する必要がありました。

Loggerは必ず classを定義する必要あるので src/logger.tsファイルにあらかじめ実装されているLoggerクラスを修正すればよかったのですが、 Resultはほとんどの実装、テストも含め参照されていることが多かったので修正箇所が大量にありました。ただ、中身は一緒なので参照を修正し、テストが通ればOKでした。

導入後、運用

実際に導入後、commonに実装した機能で新しくバグが見つかったことがありましたが、今までと違って一箇所だけを修正、あとはそれぞれで参照しているpackageバージョンを更新すれば反映できたのでとても楽でした。また、新しく共通化できるロジックは積極的に導入を進めています。テストは境界値テストを中心になるべく網羅できるようテストを書いているので、移動してきたロジックが実は間違っていたといったケースもありました。これも修正は一箇所ですむようになるので工数削減につながっています。

作ってみた感想

山浦

npm packageを作る際に気をつけることなど新しく勉強できました。今回作った共通packageにLoggerを入れていて、datadogやCLI上でのログの形式がそろったことで視認性が上がったと感じています。修正コストが大きく減ったことも身をもって実感しています。今後は複数のサーバ間での共通ロジックなど共通かできる部分もあると思うのでその際には今回の取り組みを活かしたいです。

國藤

npmパッケージ化のメリットは、複数の関連するプロジェクトを管理する際に特に顕著であることを、この経験を通じて実感しました。Plugoではサーバー間やフロントエンドとの通信プロトコルにgRPCを使用しており、インターフェースをProtocol Buffersで定義しています。CIで生成されたAPIクライアントを、gitサブモジュールとして各サーバーにインポートして使用しています。今回の経験を踏まえ、将来的にはこの実装もプライベートパッケージとして管理していきたいです。

参考

Node.js ランタイム | Google Cloud Functions に関するドキュメント