# 安裝套件 ``` npm i @grpc/grpc-js @grpc/proto-loader npm i @nestjs/microservices@9.0.0 npm i -D ts-proto ``` # 修改nest-cli.json ```json= "compilerOptions": { "assets": ["**/*.proto"], "watchAssets": true } ``` # 新增proto檔 ```protobuf= syntax = "proto3"; package echo; service EchoService { rpc EchoMessage(EchoRequest) returns (EchoResponse); } message EchoRequest{ string name = 1; } message EchoResponse { string name = 1; string timestamp = 2; } ``` # 加入Makefile ``` DIRNAME:= src/protos proto: protoc --plugin=node_modules/ts-proto/protoc-gen-ts_proto \ $(DIRNAME)/*.proto -I. \ --ts_proto_out=. \ --ts_proto_opt=fileSuffix=.pb \ --ts_proto_opt=nestJs=true \ --ts_proto_opt=addGrpcMetadata=false \ --ts_proto_opt=addNestjsRestParameter=false clean: rm -rf $(DIRNAME)/*.pb.ts ``` # 產生的型別 * Server端介面: xxxServiceController * Client端介面: xxxServiceClient * package名稱: xxx_PACKAGE_NAME * service名稱: xxx_SERVICE_NAME * GrpcMethod修飾詞: xxxServiceControllerMethods # Server端 * grpcs需設定credentials ```typescript= import { NestFactory } from '@nestjs/core'; import { AppModule } from './app.module'; import { Transport } from '@nestjs/microservices'; async function bootstrap() { const app = await NestFactory.create(AppModule); app.connectMicroservice({ transport: Transport.GRPC, options: { url: 'localhost:50051', package: 'echo', protoPath: __dirname + '/echo/echo.proto', }, }); app.startAllMicroservices(); app.listen(3000); } bootstrap(); ``` ```typescript= @Controller() @EchoServiceControllerMethods() export class EchoController implements EchoServiceController { echoMessage( request: EchoRequest, ): EchoResponse | Promise<EchoResponse> | Observable<EchoResponse> { return { name: request.name, timestamp: Date.now().toString(), }; } } ``` # Client端 ```typescript= import { Module } from '@nestjs/common'; import { HelloController } from './hello.controller'; import { ClientsModule, Transport } from '@nestjs/microservices'; import { ECHO_PACKAGE_NAME, ECHO_SERVICE_NAME } from 'src/echo/echo.pb'; import { HelloService } from './hello.service'; @Module({ imports: [ ClientsModule.register([ { name: ECHO_SERVICE_NAME, transport: Transport.GRPC, options: { url: 'localhost:50051', package: ECHO_PACKAGE_NAME, protoPath: __dirname + '/../echo/echo.proto', }, }, ]), ], controllers: [HelloController], providers: [HelloService], }) export class HelloModule {} ``` ```typescript= @Injectable() export class HelloService { private svc: EchoServiceClient; constructor( @Inject(ECHO_SERVICE_NAME) private readonly client: ClientGrpc, ) { this.svc = this.client.getService<EchoServiceClient>(ECHO_SERVICE_NAME); } hello() { return this.svc.echoMessage({ name: 'abc' }); } } ```