# Microservices ด้วย NestJS ปี 2026: สถาปัตยกรรม, gRPC และคำถามสัมภาษณ์งาน > คู่มือฉบับสมบูรณ์เรื่องสถาปัตยกรรม NestJS Microservices กับ gRPC: transport layer, Protocol Buffers, streaming patterns และคำถามสัมภาษณ์งานสำหรับ backend engineer ปี 2026 - Published: 2026-05-26 - Updated: 2026-05-26 - Author: SharpSkill - Tags: nestjs, microservices, grpc, nodejs, typescript - Reading time: 10 min --- Microservices Architecture กับ NestJS ในปี 2026 ถือเป็นหนึ่งในหัวข้อที่ได้รับความนิยมอย่างมากในวงการพัฒนาซอฟต์แวร์ NestJS ได้กลายเป็น Framework ชั้นนำสำหรับการสร้างแอปพลิเคชันฝั่ง Server ด้วย Node.js โดยเฉพาะอย่างยิ่งในการพัฒนาระบบ Microservices ที่ต้องการความยืดหยุ่นและความสามารถในการขยายตัว บทความนี้จะนำเสนอสถาปัตยกรรมของ NestJS Microservices การใช้งาน gRPC รวมถึงคำถามสัมภาษณ์งานที่พบบ่อยในปี 2026 > **gRPC เทียบกับ REST ในระบบ Microservices** > > gRPC ให้ประสิทธิภาพที่สูงกว่า REST อย่างมากเนื่องจากใช้ Protocol Buffers แทน JSON และรองรับ HTTP/2 ซึ่งช่วยลด Latency และเพิ่ม Throughput สำหรับการสื่อสารระหว่าง Services ภายในระบบ อย่างไรก็ตาม REST ยังคงเหมาะสมสำหรับ Public API ที่ต้องการความง่ายในการใช้งาน ## NestJS Microservices Transport Layer Architecture NestJS รองรับ Transport Layer หลายประเภทสำหรับการสื่อสารระหว่าง Microservices ได้แก่ TCP, Redis, NATS, RabbitMQ, Kafka และ gRPC แต่ละ Transport มีข้อดีและข้อเสียที่แตกต่างกัน การเลือกใช้ขึ้นอยู่กับความต้องการของระบบ หัวใจสำคัญของ NestJS Microservices อยู่ที่การใช้ Decorator สองตัวหลัก ได้แก่ `@MessagePattern` และ `@EventPattern` ซึ่งมีความแตกต่างกันดังนี้: - **@MessagePattern** ใช้สำหรับรูปแบบ Request-Response ที่ผู้เรียกต้องการรอรับผลลัพธ์กลับมา - **@EventPattern** ใช้สำหรับรูปแบบ Fire-and-Forget ที่ไม่ต้องการผลลัพธ์กลับ เหมาะสำหรับ Event-Driven Architecture ใน NestJS เวอร์ชัน 11 มีการเพิ่ม Method `unwrap()` ซึ่งช่วยให้การจัดการ Error จาก Microservices ทำได้ง่ายขึ้น โดย `unwrap()` จะแปลง RpcException ให้เป็น Native Error ที่สามารถ Catch ได้ในฝั่ง Client ```typescript // orders.controller.ts 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); } } ``` การออกแบบ Controller ในลักษณะนี้ช่วยให้สามารถแยกความรับผิดชอบได้อย่างชัดเจน Method ที่ใช้ `@MessagePattern` จะ Return ค่ากลับไปยังผู้เรียก ในขณะที่ Method ที่ใช้ `@EventPattern` จะทำงานแบบ Asynchronous โดยไม่มีการส่งค่ากลับ ## การตั้งค่า gRPC เป็น NestJS Microservice Transport gRPC เป็น Remote Procedure Call Framework ที่พัฒนาโดย Google ซึ่งใช้ Protocol Buffers เป็นรูปแบบในการ Serialize ข้อมูล การใช้ gRPC กับ NestJS ต้องเริ่มจากการกำหนด Service Definition ในไฟล์ .proto ```protobuf // proto/users.proto 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 นี้กำหนด Service ชื่อ `UsersService` ที่มี Method สองตัว ได้แก่ `FindOne` สำหรับค้นหาผู้ใช้ตาม ID และ `FindMany` สำหรับค้นหาผู้ใช้หลายคนแบบ Streaming การ Bootstrap gRPC Server ใน NestJS ทำได้ดังนี้: ```typescript // main.ts 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( AppModule, { transport: Transport.GRPC, options: { package: 'users', protoPath: join(__dirname, 'proto/users.proto'), url: '0.0.0.0:5000', }, }, ); await app.listen(); } bootstrap(); ``` การตั้งค่านี้จะสร้าง gRPC Server ที่รับฟังบน Port 5000 โดยใช้ Package `users` ตามที่กำหนดในไฟล์ .proto สำหรับ Controller ที่รองรับ gRPC Method ต้องใช้ Decorator `@GrpcMethod` แทน `@MessagePattern`: ```typescript // users.controller.ts 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); } } ``` ## รูปแบบ gRPC Streaming ใน NestJS gRPC รองรับการ Streaming ข้อมูลหลายรูปแบบ ได้แก่ Server Streaming, Client Streaming และ Bidirectional Streaming การใช้ Server Streaming ใน NestJS ต้องอาศัย RxJS Observable ในการส่งข้อมูลทีละชิ้น ```typescript // users.controller.ts — server streaming 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 { // 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, })), ); } ``` Server Streaming เหมาะสำหรับกรณีที่ต้องส่งข้อมูลจำนวนมากกลับไปยัง Client โดยไม่ต้องรอให้ Query เสร็จสมบูรณ์ทั้งหมด ซึ่งช่วยลด Memory Usage และปรับปรุง Time to First Byte Bidirectional Streaming ช่วยให้ทั้ง Client และ Server สามารถส่งข้อมูลหากันได้พร้อมกัน เหมาะสำหรับ Real-time Applications เช่น Chat หรือ Live Dashboard > **การจัดการ Error ใน Streaming** > > เมื่อใช้ gRPC Streaming ควรระมัดระวังในการจัดการ Error เนื่องจาก Error ที่เกิดขึ้นระหว่างการ Stream จะทำให้ Stream ถูกยกเลิกทันที ควรใช้ catchError Operator จาก RxJS เพื่อจัดการ Error และส่ง Fallback Value หรือ Retry ตามความเหมาะสม ## Hybrid Applications: HTTP และ gRPC บน Service เดียวกัน ในหลายสถานการณ์ ระบบต้องการให้บริการทั้ง HTTP API สำหรับ External Client และ gRPC สำหรับการสื่อสารภายในระหว่าง Services NestJS รองรับการสร้าง Hybrid Application ที่สามารถรันทั้งสอง Protocol พร้อมกันได้ ```typescript // main.ts — hybrid application 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({ 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(); ``` การตั้งค่านี้ช่วยให้ Service เดียวสามารถรับ Request จาก HTTP บน Port 3000 และ gRPC บน Port 5000 ได้พร้อมกัน ซึ่งเหมาะสำหรับการค่อยๆ Migrate จาก Monolith ไปสู่ Microservices ## Service Boundaries และ Domain-Driven Design กับ NestJS การออกแบบ Microservices ที่ดีต้องคำนึงถึง Service Boundaries ที่เหมาะสม หลักการ Domain-Driven Design (DDD) ช่วยให้สามารถกำหนดขอบเขตของแต่ละ Service ได้อย่างมีประสิทธิภาพ แนวทางหลักในการกำหนด Service Boundaries มีดังนี้: **Bounded Context** แต่ละ Service ควรรับผิดชอบ Domain เดียวที่มีความเกี่ยวข้องกันอย่างชัดเจน เช่น Orders Service, Users Service หรือ Payments Service **Aggregate Root** ใช้ Aggregate Pattern ในการจัดกลุ่ม Entity ที่ต้องการ Transactional Consistency เข้าด้วยกัน การเปลี่ยนแปลงข้อมูลควรทำผ่าน Aggregate Root เท่านั้น **Event Storming** ใช้เทคนิค Event Storming ในการค้นหา Domain Events และกำหนด Service Boundaries จาก Event ที่เกิดขึ้นในระบบ NestJS Module System สนับสนุนการแบ่ง Bounded Context ได้อย่างเป็นธรรมชาติ แต่ละ Module สามารถ Encapsulate Logic ของ Domain นั้นๆ และ Export เฉพาะ Interface ที่จำเป็น ## Reliability Patterns: Timeouts, Retries และ Circuit Breakers ในระบบ Microservices ความน่าเชื่อถือเป็นสิ่งสำคัญอย่างยิ่ง การสื่อสารระหว่าง Services อาจล้มเหลวได้จากหลายสาเหตุ เช่น Network Latency, Service Unavailability หรือ Resource Exhaustion การใช้ Timeout และ Retry Pattern ใน NestJS สามารถทำได้ด้วย RxJS Operators: ```typescript // orders.service.ts 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 }; } } ``` โค้ดนี้แสดงการใช้งาน Timeout 3 วินาที และ Retry สูงสุด 2 ครั้งพร้อม Exponential Backoff และ Jitter เพื่อป้องกัน Thundering Herd Problem **Circuit Breaker Pattern** เป็นอีกหนึ่ง Pattern ที่สำคัญในการป้องกันไม่ให้ Failure แพร่กระจายไปทั้งระบบ เมื่อ Service หนึ่งล้มเหลวเกินจำนวนครั้งที่กำหนด Circuit จะ Open และ Request ใหม่จะถูก Reject ทันทีโดยไม่ต้องรอ Timeout สามารถใช้ Library เช่น `opossum` หรือ `cockatiel` ร่วมกับ NestJS เพื่อ Implement Circuit Breaker Pattern ได้ > **การส่งต่อ Trace ใน NestJS 11** > > NestJS 11 รองรับการส่งต่อ Trace Context ระหว่าง Services โดยอัตโนมัติเมื่อใช้ร่วมกับ OpenTelemetry ซึ่งช่วยให้สามารถติดตาม Request ที่ผ่านหลาย Services ได้อย่างครบถ้วน ควรตั้งค่า Tracing ตั้งแต่เริ่มต้นโปรเจกต์เพื่อความสะดวกในการ Debug ## คำถามสัมภาษณ์งาน NestJS Microservices ส่วนนี้รวบรวมคำถามสัมภาษณ์งานที่พบบ่อยเกี่ยวกับ NestJS Microservices พร้อมคำตอบที่ครอบคลุม **คำถามที่ 1: อธิบายความแตกต่างระหว่าง @MessagePattern และ @EventPattern** คำตอบ: `@MessagePattern` ใช้สำหรับ Request-Response Pattern ที่ผู้เรียกต้องการรอรับผลลัพธ์กลับมา เหมาะสำหรับการ Query ข้อมูลหรือ Command ที่ต้องการยืนยันผลลัพธ์ ในขณะที่ `@EventPattern` ใช้สำหรับ Fire-and-Forget Pattern ที่ไม่ต้องการผลลัพธ์กลับ เหมาะสำหรับการแจ้ง Event ให้ Services อื่นทราบโดยไม่ต้องรอการตอบกลับ **คำถามที่ 2: gRPC ให้ข้อดีอะไรเหนือกว่า REST ในระบบ Microservices** คำตอบ: gRPC ให้ข้อดีหลายประการ ได้แก่ ประสิทธิภาพที่สูงกว่าเนื่องจากใช้ Protocol Buffers ที่ Serialize ข้อมูลได้เล็กกว่า JSON, รองรับ HTTP/2 ที่ช่วยให้ Multiplexing ได้, มี Strongly Typed Contract จาก .proto file ที่ช่วยป้องกัน Breaking Changes, และรองรับ Streaming ทั้ง Server-side, Client-side และ Bidirectional **คำถามที่ 3: อธิบายวิธีการ Implement Circuit Breaker ใน NestJS** คำตอบ: Circuit Breaker สามารถ Implement ได้โดยใช้ Library เช่น `opossum` หรือ `cockatiel` Circuit มีสามสถานะ ได้แก่ Closed (ทำงานปกติ), Open (Reject Request ทันที) และ Half-Open (ทดสอบว่า Service กลับมาทำงานปกติหรือยัง) เมื่อ Failure เกิน Threshold Circuit จะ Open และหลังจากผ่าน Reset Timeout จะเข้าสู่สถานะ Half-Open เพื่อทดสอบ **คำถามที่ 4: วิธีการจัดการ Distributed Transactions ในระบบ Microservices** คำตอบ: มีหลายแนวทาง ได้แก่ Saga Pattern ที่ใช้ Compensating Transactions เพื่อ Rollback เมื่อเกิด Failure, Outbox Pattern ที่เก็บ Event ในตารางเดียวกับ Business Data แล้วใช้ CDC หรือ Polling ส่ง Event, และ Event Sourcing ที่เก็บทุก State Change เป็น Event แล้ว Replay เมื่อต้องการ **คำถามที่ 5: อธิบายความแตกต่างระหว่าง Hybrid Application กับ Standalone Microservice ใน NestJS** คำตอบ: Standalone Microservice สร้างด้วย `NestFactory.createMicroservice()` รองรับเฉพาะ Transport ที่กำหนดเพียงตัวเดียว ในขณะที่ Hybrid Application สร้างด้วย `NestFactory.create()` แล้วเชื่อมต่อ Microservices เพิ่มเติมด้วย `app.connectMicroservice()` ช่วยให้ Service เดียวรองรับทั้ง HTTP และ Transport อื่นๆ พร้อมกัน สำหรับการเตรียมตัวสัมภาษณ์งานเพิ่มเติม สามารถศึกษาเรื่อง [NestJS modules and dependency injection](/technologies/node-nestjs/interview-questions/nestjs-modules-di) และ [middleware and interceptors](/technologies/node-nestjs/interview-questions/middleware-interceptors) เพื่อความเข้าใจที่ครอบคลุมยิ่งขึ้น ## สรุป การพัฒนา Microservices ด้วย NestJS ในปี 2026 มีความสมบูรณ์แบบมากยิ่งขึ้น ประเด็นสำคัญที่ควรจดจำมีดังนี้: - **Transport Layer** ของ NestJS รองรับหลาย Protocol และใช้ `@MessagePattern` สำหรับ Request-Response และ `@EventPattern` สำหรับ Event-Driven - **gRPC** ให้ประสิทธิภาพสูงกว่า REST และรองรับ Streaming หลายรูปแบบ เหมาะสำหรับการสื่อสารภายในระบบ - **Hybrid Application** ช่วยให้ Service เดียวรองรับทั้ง HTTP และ gRPC พร้อมกัน เหมาะสำหรับการ Migrate ไปสู่ Microservices - **Domain-Driven Design** ช่วยกำหนด Service Boundaries ที่เหมาะสมผ่าน Bounded Context และ Aggregate Pattern - **Reliability Patterns** เช่น Timeout, Retry และ Circuit Breaker เป็นสิ่งจำเป็นสำหรับระบบ Production - **NestJS 11** เพิ่มความสามารถใหม่ เช่น `unwrap()` และ Trace Propagation ที่ช่วยในการพัฒนาและ Debug --- Source: SharpSkill (https://sharpskill.dev), tech interview preparation for your real stack. HTML version of this page: https://sharpskill.dev/th/blog/node-nestjs/nestjs-microservices-grpc-architecture