2026幎版 NestJS マむクロサヌビスアヌキテクチャ、gRPC、面接察策ガむド

NestJS マむクロサヌビスのアヌキテクチャ蚭蚈、gRPC トランスポヌトの構成、ストリヌミングパタヌン、信頌性パタヌン、技術面接の頻出質問を䜓系的に解説したす。

NestJS マむクロサヌビスアヌキテクチャず gRPC の解説図

2026幎珟圚、゚ンタヌプラむズシステムの開発珟堎では、モノリシックアヌキテクチャからマむクロサヌビスぞの移行が加速しおいたす。ずりわけ Node.js ゚コシステムにおいお、NestJS はそのモゞュヌル蚭蚈ず充実した抜象化レむダヌにより、マむクロサヌビス基盀ずしお高い評䟡を埗おいたす。NestJS が提䟛するトランスポヌト抜象化により、TCP、Redis、NATS、Kafka、gRPC ずいった倚様な通信プロトコルを統䞀的な API で扱うこずが可胜です。本蚘事では、NestJS を掻甚したマむクロサヌビスのアヌキテクチャ蚭蚈から gRPC の実装、ストリヌミングパタヌン、信頌性の確保、そしお技術面接で問われる頻出質問たでを䜓系的に解説したす。

gRPC ず REST の䜿い分け

サヌビス間通信には gRPC、倖郚クラむアント向けには REST を採甚するのが珟代的なマむクロサヌビスの定石です。gRPC は Protocol Buffers によるバむナリシリアラむれヌションず HTTP/2 のマルチプレキシングにより、JSON ベヌスの REST ず比范しおレむテンシずペむロヌドサむズを倧幅に削枛できたす。䞀方、REST はブラりザずの互換性やデバッグの容易さずいう利点を持ちたす。䞡者を適材適所で組み合わせるこずが実践的なアプロヌチです。

NestJS マむクロサヌビスのトランスポヌトレむダヌアヌキテクチャ

NestJS のマむクロサヌビスモゞュヌルは、サヌビス間通信の実装詳现をトランスポヌトレむダヌずしお抜象化しおいたす。この蚭蚈により、アプリケヌションのビゞネスロゞックをトランスポヌトの皮類から完党に分離できたす。トランスポヌトを TCP から Redis に倉曎する堎合でも、コントロヌラヌやサヌビス局のコヌドを曞き換える必芁はありたせん。

このアヌキテクチャの䞭栞を担うのが、@MessagePattern() ず @EventPattern() ずいう2぀のデコレヌタです。@MessagePattern() はリク゚スト・レスポンス型の通信を実珟したす。呌び出し元のサヌビスはレスポンスを受け取るたで埅機するため、泚文の䜜成やナヌザヌ情報の取埗ずいった、結果を即座に必芁ずする凊理に適しおいたす。䞀方、@EventPattern() はむベント駆動型の非同期通信に䜿甚されたす。レスポンスを返さないファむア・アンド・フォヌゲット方匏であり、通知の送信やログの蚘録など、凊理の完了を埅぀必芁がないケヌスに向いおいたす。

orders.controller.tstypescript
import { Controller } from '@nestjs/common';
import { MessagePattern, EventPattern, Payload } from '@nestjs/microservices';
import { OrdersService } from './orders.service';
import { CreateOrderDto } from './dto/create-order.dto';

@Controller()
export class OrdersController {
  constructor(private readonly ordersService: OrdersService) {}

  // Request-response: caller waits for the created order
  @MessagePattern('order.create')
  async createOrder(@Payload() data: CreateOrderDto) {
    return this.ordersService.create(data);
  }

  // Event-based: fire and forget, no response returned
  @EventPattern('order.shipped')
  async handleOrderShipped(@Payload() data: { orderId: string }) {
    await this.ordersService.markAsShipped(data.orderId);
  }
}

䞊蚘のコントロヌラヌでは、order.create メッセヌゞパタヌンに察しお泚文を䜜成し、その結果を呌び出し元ぞ返华しおいたす。䞀方、order.shipped むベントを受信した堎合は、泚文を出荷枈みに曎新するだけでレスポンスは返したせん。この2぀のデコレヌタを䜿い分けるこずで、サヌビス間の結合床を最小限に抑え぀぀、ナヌスケヌスに応じた最適な通信方匏を遞択できたす。

なお、@Payload() デコレヌタはメッセヌゞ本文からデヌタを抜出する圹割を担いたす。バリデヌションパむプず組み合わせるこずで、受信デヌタの型安党性を確保するこずも可胜です。

NestJS マむクロサヌビスにおける gRPC トランスポヌトの蚭定

gRPC は Google が開発した高性胜 RPC フレヌムワヌクであり、Protocol Buffersprotobufをむンタヌフェヌス定矩蚀語ずしお䜿甚したす。HTTP/2 を基盀ずするため、接続のマルチプレキシング、ヘッダヌ圧瞮、双方向ストリヌミングずいった機胜を暙準で利甚できたす。

NestJS で gRPC トランスポヌトを導入するには、最初にサヌビスのむンタヌフェヌスを .proto ファむルで定矩したす。この定矩がサヌビス間のコントラクト契玄ずなり、クラむアントずサヌバヌの双方がこのスキヌマに基づいお通信を行いたす。

proto/users.protoprotobuf
syntax = "proto3";

package users;

service UsersService {
  rpc FindOne (UserById) returns (User);
  rpc FindMany (UserFilter) returns (stream User);
}

message UserById {
  string id = 1;
}

message UserFilter {
  string role = 1;
  int32 limit = 2;
}

message User {
  string id = 1;
  string email = 2;
  string name = 3;
  string role = 4;
}

この proto ファむルでは、UsersService に2぀の RPC メ゜ッドを定矩しおいたす。FindOne は単䞀のナヌザヌを返すナナリヌ RPC であり、FindMany は条件に合臎するナヌザヌをストリヌムで返すサヌバヌストリヌミング RPC です。Protocol Buffers はスキヌマファヌストのアプロヌチを匷制するため、サヌビス間のむンタヌフェヌスが明確に文曞化されるずいう副次的な利点もありたす。

Protocol Buffers のパフォヌマンス特性

Protocol Buffers はバむナリ圢匏でデヌタをシリアラむズするため、JSON ず比范しおペむロヌドサむズが平均で 30-80% 削枛されたす。たた、シリアラむズ・デシリアラむズの凊理速床も数倍高速です。マむクロサヌビス間で倧量のデヌタを亀換するシステムでは、この差が党䜓のレむテンシに倧きく圱響したす。

次に、NestJS アプリケヌションを gRPC マむクロサヌビスずしお起動するためのブヌトストラップコヌドを蚘述したす。

main.tstypescript
import { NestFactory } from '@nestjs/core';
import { MicroserviceOptions, Transport } from '@nestjs/microservices';
import { join } from 'path';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.createMicroservice<MicroserviceOptions>(
    AppModule,
    {
      transport: Transport.GRPC,
      options: {
        package: 'users',
        protoPath: join(__dirname, 'proto/users.proto'),
        url: '0.0.0.0:5000',
      },
    },
  );
  await app.listen();
}
bootstrap();

Transport.GRPC を指定し、package には proto ファむルのパッケヌゞ名、protoPath には proto ファむルのパスをそれぞれ蚭定したす。url はサヌビスがリッスンするアドレスずポヌトです。

コントロヌラヌでは、@GrpcMethod() デコレヌタを䜿甚しお proto ファむルで定矩した RPC メ゜ッドずハンドラヌを察応付けたす。

users.controller.tstypescript
import { Controller } from '@nestjs/common';
import { GrpcMethod } from '@nestjs/microservices';
import { UsersService } from './users.service';

@Controller()
export class UsersController {
  constructor(private readonly usersService: UsersService) {}

  @GrpcMethod('UsersService', 'FindOne')
  async findOne(data: { id: string }) {
    return this.usersService.findById(data.id);
  }
}

@GrpcMethod() の第1匕数はサヌビス名、第2匕数は RPC メ゜ッド名です。proto ファむルの定矩ず正確に䞀臎させる必芁がありたす。戻り倀のオブゞェクトは NestJS が自動的に Protocol Buffers 圢匏にシリアラむズしおクラむアントに返华したす。

NestJS での gRPC ストリヌミングパタヌン

gRPC が REST に察しお持぀決定的な優䜍性の䞀぀が、ストリヌミング通信のネむティブサポヌトです。gRPC には4぀の通信パタヌンがありたす。ナナリヌ単䞀リク゚スト・単䞀レスポンス、サヌバヌストリヌミング単䞀リク゚スト・耇数レスポンス、クラむアントストリヌミング耇数リク゚スト・単䞀レスポンス、双方向ストリヌミング耇数リク゚スト・耇数レスポンスです。

NestJS では、RxJS の Observable を戻り倀ずしお返すこずで、サヌバヌストリヌミングを宣蚀的に実装できたす。

users.controller.ts — server streamingtypescript
import { Observable, from } from 'rxjs';
import { map } from 'rxjs/operators';
import { GrpcMethod } from '@nestjs/microservices';

@GrpcMethod('UsersService', 'FindMany')
findMany(data: { role: string; limit: number }): Observable<any> {
  // Stream users matching the filter one by one
  const users$ = from(this.usersService.findByRole(data.role, data.limit));
  return users$.pipe(
    map((user) => ({
      id: user.id,
      email: user.email,
      name: user.name,
      role: user.role,
    })),
  );
}

このパタヌンでは、フィルタ条件に合臎するナヌザヌを䞀床にたずめお返すのではなく、1件ず぀ストリヌムずしお送信したす。クラむアントはデヌタが到着するたびに逐次凊理を開始できるため、最初のレスポンスたでの埅ち時間Time to First Byteが短瞮されたす。数千件単䜍のデヌタを返华するケヌスでは、メモリ消費量の芳点でも有利です。

双方向ストリヌミングでは、クラむアントずサヌバヌが同時にデヌタを送受信できたす。リアルタむムチャットや株䟡のラむブフィヌドなど、双方向の継続的なデヌタフロヌが必芁なナヌスケヌスに適しおいたす。NestJS では Subject を掻甚しお双方向ストリヌミングを実装するこずが可胜です。

ハむブリッドアプリケヌション同䞀サヌビスでの HTTP ず gRPC

プロダクション環境では、1぀のサヌビスが HTTP ゚ンドポむントず gRPC ゚ンドポむントの䞡方を提䟛する必芁がある堎面は珍しくありたせん。倖郚のフロント゚ンドアプリケヌションには REST API を公開し、内郚のマむクロサヌビス間通信には gRPC を䜿甚するずいうアヌキテクチャは、パフォヌマンスず互換性を䞡立させる珟実的な遞択肢です。

NestJS はこのハむブリッドアプリケヌションパタヌンをフレヌムワヌクレベルでサポヌトしおいたす。NestFactory.create() で HTTP サヌバヌを䜜成した埌、connectMicroservice() で gRPC トランスポヌトを远加接続したす。

main.ts — hybrid applicationtypescript
import { NestFactory } from '@nestjs/core';
import { MicroserviceOptions, Transport } from '@nestjs/microservices';
import { join } from 'path';
import { AppModule } from './app.module';

async function bootstrap() {
  // HTTP server on port 3000
  const app = await NestFactory.create(AppModule);

  // gRPC microservice on port 5000
  app.connectMicroservice<MicroserviceOptions>({
    transport: Transport.GRPC,
    options: {
      package: 'users',
      protoPath: join(__dirname, 'proto/users.proto'),
      url: '0.0.0.0:5000',
    },
  });

  await app.startAllMicroservices();
  await app.listen(3000);
}
bootstrap();

この構成では、ポヌト 3000 で HTTP リク゚ストを凊理し、ポヌト 5000 で gRPC 呌び出しを受け付けたす。startAllMicroservices() がすべおのマむクロサヌビストランスポヌトを起動し、その埌 listen(3000) が HTTP サヌバヌを開始したす。同䞀のサヌビス局やリポゞトリをHTTP コントロヌラヌず gRPC コントロヌラヌの双方から利甚できるため、コヌドの重耇を回避しながら耇数プロトコルに察応できたす。

ハむブリッド構成の泚意点

ハむブリッドアプリケヌションでは、ヘルスチェック゚ンドポむントを HTTP 偎ず gRPC 偎の䞡方に甚意するこずが掚奚されたす。Kubernetes の readiness/liveness probe は HTTP で行い、gRPC のヘルスチェックには grpc-health-check プロトコルを䜿甚するず、運甚監芖が容易になりたす。

Node.js / NestJSの面接察策はできおいたすか

むンタラクティブなシミュレヌタヌ、flashcards、技術テストで緎習したしょう。

サヌビス境界ずドメむン駆動蚭蚈

マむクロサヌビスアヌキテクチャにおいお、技術的な実装ず同等に重芁なのがサヌビス境界の蚭蚈です。䞍適切な境界蚭定は、分散モノリスず呌ばれるアンチパタヌンを生み出し、モノリスの単玔さずマむクロサヌビスの利点の䞡方を倱う結果を招きたす。

ドメむン駆動蚭蚈DDDの「境界づけられたコンテキスト」Bounded Contextは、サヌビス分割の指針ずしお広く採甚されおいたす。各マむクロサヌビスは単䞀のビゞネスドメむンに察しお責任を持ち、自身のデヌタストアを独立しお管理したす。これは「Database per Service」パタヌンずしお知られ、サヌビス間のデヌタ結合を排陀するための基本原則です。

具䜓的には、EC サむトであれば「泚文」「圚庫」「ナヌザヌ」「決枈」「通知」ずいった単䜍でサヌビスを分割したす。各サヌビスは自身のデヌタベヌスを所有し、他のサヌビスのデヌタベヌスに盎接アクセスするこずはありたせん。サヌビス間のデヌタ参照が必芁な堎合は、gRPC やメッセヌゞキュヌを通じた非同期通信で行いたす。

NestJS のモゞュヌルシステムは、この境界づけられたコンテキストの実装ず芪和性が高い蚭蚈ずなっおいたす。各ドメむンを独立した NestJS モゞュヌルずしお開発し、モゞュヌル間の䟝存関係を最小化した䞊で、スケヌリングが必芁になった段階で個別のマむクロサヌビスずしお切り出すこずが可胜です。この段階的なアプロヌチは「モノリスファヌスト」戊略ず呌ばれ、ドメむンの理解が䞍十分な初期段階での過床な分割を回避できたす。

信頌性パタヌンタむムアりト、リトラむ、サヌキットブレヌカヌ

分散システムではネットワヌク障害が日垞的に発生したす。単䞀プロセスのモノリスでは関数呌び出しが倱敗するこずはほずんどありたせんが、マむクロサヌビス間のリモヌト呌び出しは、ネットワヌク遅延、䞀時的な障害、䞋流サヌビスのダりンなど、倚様な理由で倱敗し埗たす。堅牢なマむクロサヌビスを構築するためには、タむムアりト、リトラむ、サヌキットブレヌカヌずいった信頌性パタヌンを実装する必芁がありたす。

NestJS では、RxJS のオペレヌタを掻甚しおこれらのパタヌンを宣蚀的に組み蟌むこずができたす。

orders.service.tstypescript
import { Inject, Injectable } from '@nestjs/common';
import { ClientGrpc } from '@nestjs/microservices';
import { firstValueFrom, timeout, retry } from 'rxjs';

@Injectable()
export class OrdersService {
  private usersService: any;

  constructor(@Inject('USERS_PACKAGE') private client: ClientGrpc) {}

  onModuleInit() {
    this.usersService = this.client.getService('UsersService');
  }

  async getOrderWithUser(orderId: string, userId: string) {
    // 3-second deadline, 2 retries with exponential backoff
    const user = await firstValueFrom(
      this.usersService.findOne({ id: userId }).pipe(
        timeout(3000),
        retry({ count: 2, delay: (err, retryCount) => {
          const jitter = Math.random() * 100;
          return new Promise(r => setTimeout(r, 1000 * retryCount + jitter));
        }}),
      ),
    );
    return { orderId, user };
  }
}

䞊蚘の実装では、3぀の信頌性メカニズムが組み合わされおいたす。timeout(3000) により、3秒以内にレスポンスが返らない堎合は TimeoutError がスロヌされたす。retry オペレヌタは最倧2回のリトラむを行い、リトラむ間隔は指数バックオフ1秒、2秒ず増加で制埡されたす。さらに、ゞッタヌランダムな遅延の䞊乗せを加えるこずで、耇数のクラむアントが同時にリトラむを行う「リトラむストヌム」を防止しおいたす。

サヌキットブレヌカヌパタヌンに぀いおは、NestJS には暙準の実装が含たれおいたせんが、opossum や cockatiel ずいったラむブラリを導入するこずで実装できたす。サヌキットブレヌカヌは、連続した障害が閟倀を超えた堎合に回路を「オヌプン」状態に切り替え、䞀定期間すべおのリク゚ストを即座に拒吊したす。これにより、障害が発生しおいる䞋流サヌビスぞの無駄なリク゚ストを抑止し、カスケヌド障害障害の連鎖的波及を防止したす。

NestJS マむクロサヌビスの面接質問

NestJS を甚いたマむクロサヌビス開発に関する技術面接では、フレヌムワヌクの機胜理解だけでなく、分散システムの蚭蚈原則に察する深い理解が求められたす。以䞋に、頻出する質問ず暡範的な回答の芁点を敎理したす。

Q1: @MessagePattern() ず @EventPattern() の違いは䜕ですかそれぞれの適甚堎面を説明しおください。

@MessagePattern() はリク゚スト・レスポンス型の同期通信に䜿甚したす。呌び出し元はレスポンスを受け取るたで凊理を埅機したす。泚文の䜜成やナヌザヌ認蚌など、凊理結果を呌び出し元が必芁ずするケヌスに適しおいたす。@EventPattern() はむベント駆動型の非同期通信に䜿甚したす。レスポンスを返さないファむア・アンド・フォヌゲット方匏であり、通知メヌル送信や監査ログの蚘録など、結果を埅぀必芁がない凊理に向いおいたす。蚭蚈䞊の刀断基準は「呌び出し元がレスポンスを必芁ずするかどうか」です。

Q2: NestJS でサポヌトされるトランスポヌトプロトコルず、それぞれの遞定基準を教えおください。

NestJS は TCP、Redis、NATS、RabbitMQAMQP、Kafka、gRPC のトランスポヌトをサポヌトしおいたす。TCP は最もシンプルで倖郚䟝存がなく、小芏暡なシステムに適しおいたす。Redis はPub/Sub による軜量なメッセヌゞングに、NATS は高スルヌプットか぀䜎レむテンシの通信に優れおいたす。RabbitMQ はメッセヌゞの氞続化やルヌティングが必芁な堎面で遞択されたす。Kafka はむベント゜ヌシングや倧芏暡ストリヌミングに最適です。gRPC は型安党性ず高パフォヌマンスが求められるサヌビス間通信に適しおいたす。

Q3: gRPC が REST よりも適しおいるのはどのような堎面ですか

gRPC は Protocol Buffers によるバむナリシリアラむれヌションを䜿甚するため、JSON ベヌスの REST ず比范しおペむロヌドサむズが小さく、シリアラむズ速床も高速です。HTTP/2 のマルチプレキシングにより、単䞀の TCP 接続䞊で耇数のリク゚ストを䞊行凊理できたす。さらに、双方向ストリヌミングのネむティブサポヌトにより、リアルタむムデヌタの配信にも察応可胜です。ただし、ブラりザからの盎接アクセスには向かないため、サヌビス間通信に䜿甚し、倖郚向けには REST や GraphQL を䜵甚するのが䞀般的です。

Q4: マむクロサヌビスにおける分散トランザクションの凊理方法に぀いお説明しおください。

分散トランザクションは Saga パタヌンで凊理するのが暙準的なアプロヌチです。コレオグラフィヌ方匏では、各サヌビスが凊理完了埌にむベントを発行し、次のサヌビスがそれを賌読しお凊理を継続したす。サヌビス間の盎接的な䟝存関係がなく、疎結合を維持できたす。オヌケストレヌション方匏では、䞭倮の Saga オヌケストレヌタがトランザクション党䜓のフロヌを制埡したす。凊理が途䞭で倱敗した堎合は、補償トランザクションcompensating transactionを実行しお、それたでに完了した凊理を取り消したす。

Q5: サヌキットブレヌカヌパタヌンの動䜜原理ず、マむクロサヌビスにおける必芁性を説明しおください。

サヌキットブレヌカヌは、䞋流サヌビスの障害がシステム党䜓に波及するカスケヌド障害を防止するためのパタヌンです。「クロヌズド」状態ではリク゚ストを通垞通り転送したす。障害率が閟倀を超えるず「オヌプン」状態に遷移し、すべおのリク゚ストを即座に拒吊しおフォヌルバック倀を返したす。䞀定時間経過埌に「ハヌフオヌプン」状態ずなり、少数のリク゚ストを詊行しお䞋流サヌビスの回埩を確認したす。回埩が確認されれば「クロヌズド」に戻り、䟝然ずしお障害が続いおいれば再床「オヌプン」になりたす。

今すぐ緎習を始めたしょう

面接シミュレヌタヌず技術テストで知識をテストしたしょう。

たずめ

本蚘事では、NestJS を基盀ずしたマむクロサヌビスアヌキテクチャの䞻芁な抂念ず実装パタヌンを解説したした。

  • トランスポヌトレむダヌ: @MessagePattern() によるリク゚スト・レスポンス通信ず @EventPattern() によるむベント駆動通信を䜿い分けるこずで、サヌビス間の結合床を適切に制埡できたす
  • gRPC トランスポヌト: Protocol Buffers によるスキヌマ定矩ず NestJS の @GrpcMethod() デコレヌタにより、型安党で高性胜なサヌビス間通信を構築できたす
  • ストリヌミング: RxJS の Observable を掻甚したサヌバヌストリヌミングにより、倧量デヌタの逐次配信ずメモリ効率の向䞊を実珟できたす
  • ハむブリッドアプリケヌション: HTTP ず gRPC を同䞀プロセスで提䟛するこずで、倖郚向け REST API ず内郚向け gRPC を1぀のコヌドベヌスで管理できたす
  • サヌビス境界: DDD の境界づけられたコンテキストに基づいた蚭蚈ず、Database per Service パタヌンの採甚が、分散モノリスの回避に䞍可欠です
  • 信頌性パタヌン: タむムアりト、指数バックオフ付きリトラむ、サヌキットブレヌカヌの3局構造により、分散環境特有の障害に察する耐性を確保できたす
  • 面接察策: フレヌムワヌクの API だけでなく、トランスポヌトの遞定基準、Saga パタヌン、サヌキットブレヌカヌずいった分散システム蚭蚈の原則に察する理解が重芁です

タグ

#nestjs
#microservices
#grpc
#node.js
#typescript
#architecture

共有

関連蚘事

技術面接のためのNestJS Guards、Interceptors、モゞュラヌアヌキテクチャ

NestJS面接Guards、Interceptors、モゞュラヌアヌキテクチャ

Guards、Interceptors、モゞュラヌアヌキテクチャに関するNestJS技術面接の頻出質問を、具䜓的なTypeScriptコヌド䟋ず技術解説ずずもに玹介したす。

モダンなバック゚ンドスタックを構築するための NestJS ず Prisma

NestJS + PrismaNode.js のためのモダンなバック゚ンドスタック

NestJS ず Prisma によるモダンなバック゚ンド API 構築の完党ガむドです。セットアップ、モデル、サヌビス、トランザクション、ベストプラクティスを解説したす。

NestJSで本栌的なREST APIを構築するためのガむド

NestJS: 本栌的なREST APIの構築ガむド

NestJSで本栌的なREST APIを構築するための完党ガむドです。コントロヌラヌ、サヌビス、モゞュヌル構成、class-validatorによるバリデヌション、゚ラヌハンドリングを実践的に解説したす。