使用nestjs集成grpc具體操作


兩個程序中, 提供grpc服務的稱為服務端, 調用grpc服務的為客戶端, 以下是grpc服務端和客戶端的代碼編寫
 

 
1. 創建兩個nestjs項目demo1(端口: 3000)和demo2(端口: 3001), demo1一個提供grpc服務,demo2調用demo1中的方法
 
  如何創建nest項目和啟動這里就不贅述了, nest官網有
 
2. 下載依賴包
npm i --save @nestjs/microservices
npm i --save grpc @grpc/proto-loader

 

3. 服務端demo1中代碼
 
     3.1 創建 cats.proto文件,此文件demo1與demo2都需要編寫這個文件, 內容一致, 名字隨便, 但必須是.proto文件
syntax = "proto3";

package first; // 包名

service CatsService {
rpc FindOne (ById) returns (Cat) {} // 暴露方法
}

// message定義結構
message ById { // 參數
int32 id = 1;
}

message Cat { // 返回類型
int32 id = 1;
string name = 2;
}
       以上cats.proto文件中, 定義了路徑/first.CatsService/FindOne
        .proto文件:  Protobuf即Protocol Buffers,是Google公司開發的一種跨語言和平台的序列化數據結構的方式,是一個靈活的、高效的用於序列化數據的協議。
 
     3.2 創建文件 grpc.option.ts, 引用.proto文件
import { Transport, ClientOptions } from '@nestjs/microservices';
import { join } from 'path';
export const grpcServerOptions: ClientOptions = {
  transport: Transport.GRPC,
  options: {
    url: 'localhost:8888', // grpc連接ip與端口
    package: 'first', // 包名 與.proto中保持一致
    protoPath: join(__dirname, '../cats.proto') // 找到cats.proto
  },
};
 
     3.3 main.ts中開啟grpc服務
 // 開啟grpc 作為grpc服務   
app.connectMicroservice(grpcServerOptions);// grpcServerOptions為3.2中的配置
app.startAllMicroservicesAsync()

 

     3.4 在相應的controller中暴露方法
import { Controller, Get, Param } from '@nestjs/common';
import { AppService } from './app.service';
import { GrpcMethod } from '@nestjs/microservices'

@Controller()
export class AppController {
  constructor(private readonly appService: AppService) {}

  // @GrpcMethod('CatsService', 'FindOne') 
  // GrpcMethod中第一個是.proto中服務, 第二個參數是暴露方法名, 不寫的話默認是方法的首字母大寫
  @GrpcMethod('CatsService', 'FindOne')
  findOne (data: {id: number}, metdata: any) {
    const items = [
      { id: 1, name: 'John' },
      { id: 2, name: 'Doe' },
    ];
    return items.find(
      ({ id }) => id === data.id
    );
  }

  @Get()
  getHello(): string {
    return this.appService.getHello();
  }

}
公開了方法:
localhost:8888/first.CatsService/FindOne



 
 
4. 客戶端demo2中的代碼編輯, 目的是使用demo1中的cats的findOne方法
     4.1 創建cats.proto文件, 與demo1中的文件一致
     4.2 創建文件grpc.client.server.ts
import { Injectable } from "@nestjs/common";
import { ClientGrpc, Client } from "@nestjs/microservices";

import { Transport, ClientOptions } from '@nestjs/microservices';
import { join } from 'path';
// 與服務端的options中配置一致
export const grpcClientOptions: ClientOptions = {
  transport: Transport.GRPC,
  options: {
    url: 'localhost:8888', // grpc連接ip與端口
    package: 'first', // 包名 與.proto中保持一致
    protoPath: join(__dirname, '../cats.proto') // 找到cats.proto
  },
};

@Injectable()
export class ClentServe {
   // 客戶端 實例 使用@Client()裝飾器 @Client(grpcClientOptions)
public readonly client: ClientGrpc; }

 

     4.3 使用
import { Controller, Get, Post, Body, Inject, OnModuleInit } from '@nestjs/common';
import { ApiOperation } from '@nestjs/swagger';
import { CreateCatsDto } from './dto/cat.dto';
import { GrpcMethod } from '@nestjs/microservices';
import { ClentServe } from 'src/grpc-client/client.serve';
import { CatsService } from 'src/grpc-client/interface/api.interface';

@Controller('cats')
export class CatsController implements OnModuleInit {
private catService
  constructor(@Inject(ClentServe) private readonly clentServe: ClentServe)  {}
  
  onModuleInit() {
  // 可以在程序中創建接口CatsService, 這樣調用方法時方便,有提示, 沒有也可以
  // this.catService = this.clentServe.client.getService<CatsService>('CatsService')
this.catService = this.clentServe.client.getService('CatsService') } @Get() index() { return this.catService.findOne({id: 2}) } @Post() createPosts (@Body() dto: CreateCatsDto) { return dto } }

 

啟動demo1與demo2, 這樣demo2就可以調用到demo1的方法了
 
 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM