สารจากนักเขียน
สวัสดีครับทุกคนวันนี้ผมจะพาทุกคนมาลองเล่น Microservice ของ NestJS กัน อันดับแรกเราก็ต้องมีพื้นฐานความเข้าใจของ Microservice ก่อน และทุกคนสามารถเข้าไป อ่านเพิ่มเติมได้ที่นี่เลย Microservice
เขียนโดย
Thapanon Sodngam
Junior Software Developer
บทความนี้ตีพิมพ์ และ เผยแพร่เมื่อ 02 กุมภาพันธ์ 2566
เอาล่ะมาลงมือทำกันเลยโดยเราจะสร้าง Nest Project มา 3 ตัวและให้ชื่อว่า
- Client เป็นตัวแทนของ App หลักที่จะคอยเรียก Service จาก Microservice ต่าง ๆ
- String-service เป็นตัวแทนของ Microservice ตัวที่ 1
- Math-service เป็นตัวแทนของ Microservice ตัวที่ 2
เรามาลง package เพิ่มเติมสำหรับทำ Nest Project ให้รองรับ Microservice กันครับ
โดยใช้คำสั่งด้านล่างลงในทุก Project
“`npm i –save @nestjs/microservices”`
หลังจากนั้นให้เราแก้ Code ใน main.ts ของ Microservice นะครับเพื่อตั้งค่าให้ Service เหล่านั้นทำตัวเป็น Microservice โดยใส่ code ตามผมได้เลย
import { NestFactory } from '@nestjs/core';
import { Transport, MicroserviceOptions } from '@nestjs/microservices';
import { AppModule } from './app.module';
import { Logger } from '@nestjs/common';
const logger = new Logger();
const PORT = 3001;
async function bootstrap() {
const app = await NestFactory.createMicroservice(
AppModule,
{
transport: Transport.TCP,
options: { port: PORT },
},
);
await app.listen();
logger.log('Mocroservice run on port ' + PORT);
}
bootstrap();
โดย Code ด้านบนจะเป็นการตั้งค่า NestJS ให้เป็น Microservice ที่สามารถเรียกได้ผ่านโปรโตคอล TCP และเราก็ตั้งค่า PORT ที่ต้องการให้ Microservice นั้นเปิดเพื่อรอ Service อื่นเรียกเข้ามานะครับ โดยผมจะตั้งค่าให้เป็น 3001 และ 3002 นะครับและเมื่อเราสั่งรัน Microservice จะได้หน้าตาออกมาแบบนี้ครับ
ต่อไปเรามาทำตัว Service กัน
Project math-service file app.controller
import { Controller, Logger } from '@nestjs/common';
import { MessagePattern } from '@nestjs/microservices';
@Controller()
export class AppController {
private logger;
constructor() {
this.logger = new Logger('MathService');
}
@MessagePattern({ cmd: 'sum' })
accumulate(data: number[]): number {
const result = (data || []).reduce((a, b) => a + b);
this.logger.log('accumulate has call result : ' + result);
return result;
}
}
import { Controller, Logger } from '@nestjs/common';
import { MessagePattern } from '@nestjs/microservices';
@Controller()
export class AppController {
private logger;
constructor() {
this.logger = new Logger('MathService');
}
@MessagePattern({ cmd: 'sum' })
accumulate(data: number[]): number {
const result = (data || []).reduce((a, b) => a + b);
this.logger.log('accumulate has call result : ' + result);
return result;
}
}
Project string-service file app.controller
import { Controller, Logger } from '@nestjs/common';
import { MessagePattern } from '@nestjs/microservices';
@Controller()
export class AppController {
private logger;
constructor() {
this.logger = new Logger('StringService');
}
@MessagePattern({ cmd: 'join' })
join(data: string[]): string {
const result = (data || []).join('-');
this.logger.log('join has call result : ' + result);
return result;
}
}
โดย Code ในส่วนนี้จะมีหน้าตาคล้าย ๆ กันโดยจะมี MessagePattern ที่คอยทำหน้าที่เหมือนกับ HTTP method ต่าง ๆ เลย และผมก็ได้ทำการเพิ่ม Log ลงไปด้วยเมื่อมีการเรียกใช้ Service
ต่อไปเราไปทำในส่วนของ Client กันต่อ
app.module.ts
import { Module } from '@nestjs/common';
import { ClientsModule, Transport } from '@nestjs/microservices';
import { AppController } from './app.controller';
import { AppService } from './app.service';
@Module({
imports: [
ClientsModule.register([
{
name: 'MATH_SERVICE',
transport: Transport.TCP,
options: { port: 3001 },
},
{
name: 'STRING_SERVICE',
transport: Transport.TCP,
options: { port: 3002 },
},
]),
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
ในส่วนนี้ก็จะเป็นการ Import ตัวของ Microservice ต่าง ๆ เข้ามาใน App Module
ต่อไปเราจะมาทำในส่วนของ Controller กันที่จะคอยเรียก Microservice ต่าง ๆ
app.controller.ts
import { Controller, Post, Inject, Body } from '@nestjs/common';
import { ClientProxy } from '@nestjs/microservices';
import { Observable } from 'rxjs';
@Controller()
export class AppController {
constructor(
@Inject('MATH_SERVICE')
private mathService: ClientProxy,
@Inject('STRING_SERVICE')
private stringService: ClientProxy,
) {}
@Post('sum')
sum(@Body() { data }): Observable {
return this.mathService.send({ cmd: 'sum' }, data);
}
@Post('join')
join(@Body() { data }): Observable {
return this.stringService.send({ cmd: 'join' }, data);
}
}
จาก Code จะมี Microservice 2 ตัวโดยแต่ละตัวจะมี Class เดียวกันนั่นก็คือ ClientProxy แต่จะแยกว่าเป็น Microservice ตัวไหนผ่าน @Inject(‘service-name’) ครับและ ใน Controller ก็มี Function ที่มี End-point /sum กับ /join ที่จะไปเรียก Service จาก Microservice ต่าง ๆ
โดย Function เราจะเรียก microservice.send<type>(message-pattern, data) โดยตัว Nest Microservice จะ return ค่ากลับมาเป็น Observable<type> ถ้าเราต้องการนำค่าไปใช้ต่อในรูปแบบของ Value ปกติก็สามารถ import lastValueFrom จาก ‘rxjs’ ใช้ได้เลยตามตัวอย่างด้านล่าง
@Post('join')
async join(@Body() { data }): Promise {
const result = await this.stringService.send({ cmd: 'join' }, data);
const final = await lastValueFrom(result);
return final;
}
ต่อมาเรามาดูผลกันเถอะ Call API ผ่าน Postman
/sum
/join
จากการลองยิง API เล่นดูก็จะเห็นได้ที่ Log ของ Microservice นั้นได้มีการ Log ว่า Function ในตัวเองนั่นมีการทำงานซึ่งผมก็ได้ Log Result ของ Function ไว้ด้วยแล้วก็จะเห็นได้ว่าผมมันตรงกับ Result ที่ Postman ได้มานั่นเองงงงงง
และก็จบไปแล้วกับการลองทำ Microservice ด้วย NestJS หวังว่าจะเป็นแนวทางให้กับหลาย ๆ คนนะครับ
ระบบฝึกทักษะ การเขียนโปรแกรม
ที่พร้อมตรวจผลงานคุณ 24 ชั่วโมง
- โจทย์ปัญหากว่า 200 ข้อ ที่รอท้าทายคุณอยู่
- รองรับ 9 ภาษาโปรแกรมหลัก ไม่ว่าจะ Java, Python, C ก็เขียนได้
- ใช้งานได้ฟรี ! ครบ 20 ข้อขึ้นไป รับ Certificate ไปเลย !!