Contents
NestJSマイクロサービス導入の背景と目的
現代のWebアプリケーションでは、スケーラビリティや柔軟な運用性を求めるニーズが高まっています。特にマイクロサービスアーキテクチャは、複雑なシステムを独立したサービスに分割し、それぞれを個別に開発・デプロイできる点で注目されています。NestJSはNode.jsベースのフレームワークであり、TypeScriptサポートや依存性注入(DI)機能により、マイクロサービス構築に最適な選択肢です。本記事では、NestJSを用いたマイクロサービス実装手順を体系的に解説し、具体的なコード例とともに実務で即活用できる知識をお届けします。
NestJSプロジェクトの初期設定手順
マイクロサービス構築はプロジェクト初期設定から始まります。NestJSのCLIツールを使用することで、効率的な環境構築が可能です。
CLIツールによるプロジェクト生成
NestJSではnest newコマンドで新規プロジェクトを生成できます。このとき--microservicesフラグを追加すると、gRPCやイベント駆動型アーキテクチャを意識した初期構成になります(※NestJS公式ドキュメントに確認が必要なため、具体的な挙動は後述します)。
|
1 2 |
npx nest new my-microservice --microservices |
このコマンドは以下を自動で実施します:
- TypeScript環境のセットアップ
- gRPCテンプレートファイルの生成(
.proto) - デフォルトのサービス・コントローラー構成
基本的なファイル構造の確認
生成されたプロジェクトでは、以下のようなディレクトリ構成ができます:
|
1 2 3 4 5 6 7 |
src/ ├── common/ # サービス間で共有する定義 ├── main.ts # アプリケーションエントリポイント ├── microservices/ # gRPC用のサービス実装 ├── modules/ # モジュールごとの構成(例: UsersModule) └── services/ # サービスロジックをまとめたディレクトリ |
この構造は単一責任原則に則り、各モジュールが独立して動作することを保証します。
マイクロサービス構成設計のベストプラクティス
マイクロサービスアーキテクチャでは「ドメイン駆動設計(DDD)」や「サービス境界線の明確化」が成功の鍵です。以下に具体的な手法を解説します。
ドメイン駆動設計の適用方法
DDDは、ビジネスロジックと技術実装を密接に連携させる設計アプローチです。例えば「注文処理」に関するドメインでは、以下のようにサービスを分離できます:
| サービス名 | 責務 |
|---|---|
| OrderService | 注文の作成・キャンセルなどのロジック |
| InventoryService | 在庫状況の更新 |
| PaymentService | 支払い処理 |
このように分離することで、各サービスが独立して開発・テスト可能になり、変更の影響範囲を最小化できます。
サービス境界線の明確化
サービス間の依存関係は、イベント駆動型アーキテクチャ(EDA)を採用することで柔軟に管理できます。例として「ユーザー登録」処理と「在庫変更」処理を考えてみましょう:
- UserRegistrationServiceがユーザー情報を保存
- 「user-created」というイベントを発火
- NotificationServiceがこのイベントを受け取り、メール送信を行う
もう1つの例として、「ProductService」が在庫を更新する際には「stock-updated」イベントを発火し、「InventoryService」がこれを処理することで、サービス間の直接呼び出しを避けます。このようにすることで、システム全体の拡張性と柔軟性を高められます。
gRPCとREST APIの選定基準
通信プロトコルとしてgRPCやREST APIはそれぞれ特徴があり、ユースケースに応じて使い分ける必要があります。
通信プロトコル比較:gRPC vs REST API
以下の表では、両プロトコルの性能や実装難易度を比較しています:
|
1 2 3 4 5 6 |
| 項目 | **gRPC** | **REST API** | |--------------|-----------------------------------|----------------------------------| | **速度** | **高速(バイナリ形式)** | 標準(JSON形式) | | **実装難易度** | 複雑(protobuf必要) | 簡単 | | **バージョン管理** | バージョンごとにスキーマ変更可 | 非推奨(クライアント側対応が必要) | |
gRPCは高頻度のデータ通信やリアルタイム処理に向いており、REST APIは汎用性が高く、API Gatewayとの連携に適しています。
メッセージ形式の選択ポイント
gRPCではProtocol Buffers(protobuf)を使用し、以下のような仕組みで動作します:
|
1 2 3 4 5 6 7 8 9 10 |
syntax = "proto3"; service User { rpc CreateUser (UserRequest) returns (UserResponse); } message UserRequest { string name = 1; } |
この.protoファイルをNestJSではprotocコマンドでコンパイルし、自動的にサービスリポジトリが生成されます。
コンテナ化によるデプロイ手順
マイクロサービスの運用にはDockerとKubernetes(K8s)の導入が不可欠です。以下に具体的な手順を示します。
Dockerイメージ構築の手順
Dockerfileを作成し、NestJSアプリケーションをビルドします:
|
1 2 3 4 5 6 7 8 |
FROM node:20 WORKDIR /app COPY package*.json ./ RUN npm install COPY . . EXPOSE 3000 CMD ["node", "dist/main"] |
このDockerイメージはdocker build -t my-microservice .でビルドし、docker runで起動可能です。
Kubernetesでのサービス配置手順
KubernetesではDeploymentとServiceを定義することで、スケーリングやロードバランシングが簡単に実現できます。以下は簡単なYAML例:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
apiVersion: apps/v1 kind: Deployment metadata: name: user-service spec: replicas: 3 selector: matchLabels: app: user-service template: metadata: labels: app: user-service spec: containers: - name: user-service image: my-microservice:latest ports: - containerPort: 3000 |
helmチャートを使うことで、複数サービスの管理を効率化できます。
サービス間通信のセキュリティ対策
マイクロサービス構築にあたっては、ネットワーク層での暗号化と認証・認可仕組みが不可欠です。
TLSによる暗号化
gRPCではmTLS(Mutual TLS)を使用することで、通信の安全性を確保できます。以下が設定手順:
opensslで証明書生成grpc.ServerCredentials.createSsl()で暗号化設定- クライアント側も同様にmTLS有効化
この設定により不正アクセスの防止と信頼性向上が期待できます。
認証・認可の実装方法
JWT(JSON Web Token)によるユーザー認証は、以下のように実装可能です:
|
1 2 3 4 5 6 |
// 認証ガード例:JWTを用いたユーザー認証処理 @Injectable() export class JwtAuthGuard extends AuthGuard('jwt') { // ガードロジックをここに記述(例: ユーザーの存在確認) } |
このガードを使用することで、各サービスに認証処理を統一し、セキュリティポリシーの貫徹が可能になります。
まとめ
本記事では以下を解説しました:
- NestJSマイクロサービスプロジェクトの初期設定手順(CLIツール・ファイル構造)
- ドメイン駆動設計とサービス境界線の明確化方法
- gRPC vs REST APIの選定基準とprotobufの使用例
- DockerとKubernetesによるコンテナ化デプロイ手順
- TLSやJWTを使ったセキュリティ対策
マイクロサービス構築では「柔軟性」と「信頼性」を両立させる設計が重要です。記事内で紹介したテンプレートコードをベースに、実際にNestJSでマイクロサービスアーキテクチャを構築してみてください。