NestJS gRPC无参Service方法调用报错:是否必须传参?
NestJS + gRPC 空请求参数报错问题
我正在学习使用NestJS和gRPC构建微服务架构,创建了一个无需传递业务参数的跨服务数据获取API,采用google.protobuf.Empty定义请求类型,但调用API时出现参数错误,添加参数后可正常运行,想问是否必须为该gRPC Service方法传递参数?
相关代码
contractAddress.proto
import "google/protobuf/empty.proto"; syntax = "proto3"; package contractAddress; service ContractAddressService { rpc getAllContractAddress (google.protobuf.Empty) returns (GetAllContractAddressResponse); } message GetAllContractAddressResponse { repeated string data = 1; }
grpc.interface.ts
export interface ContractServiceClient { getAllContractAddress(): Observable<GetAllContractAddressResponse>; }
contract.controller.ts
@Inject('CONTRACTADDRESS_PACKAGE') private client: ClientGrpc; onModuleInit(): void { this.svc = this.client.getService<ContractServiceClient>( 'ContractAddressService', ); } @Get() getContractAddres() { return this.svc.getAllContractAddress(); }
报错信息
[Nest] 77656 - 09/12/2022, 5:54:19 PM ERROR [ExceptionsHandler] Incorrect arguments passed Error: Incorrect arguments passed at ServiceClientImpl.checkOptionalUnaryResponseArguments (/Users/champerwu/Documents/Project/naos-fin-interview/naos-api/node_modules/@grpc/grpc-js/src/client.ts:224:15) at ServiceClientImpl.makeUnaryRequest (/Users/champerwu/Documents/Project/naos-fin-interview/naos-api/node_modules/@grpc/grpc-js/src/client.ts:271:35) at ServiceClientImpl.getAllContractAddress (/Users/champerwu/Documents/Project/naos-fin-interview/naos-api/node_modules/@grpc/grpc-js/src/make-client.ts:189:15) at Observable._subscribe (/Users/champerwu/Documents/Project/naos-fin-interview/naos-api/node_modules/@nestjs/microservices/client/client-grpc.js:177:35) at Observable._trySubscribe (/Users/champerwu/Documents/Project/naos-fin-interview/naos-api/node_modules/rxjs/src/internal/Observable.ts:245:19) at /Users/champerwu/Documents/Project/naos-fin-interview/naos-api/node_modules/rxjs/src/internal/Observable.ts:235:18) at Object.errorContext (/Users/champerwu/Documents/Project/naos-fin-interview/naos-api/node_modules/rxjs/src/internal/util/errorContext.ts:29:5) at Observable.subscribe (/Users/champerwu/Documents/Project/naos-fin-interview/naos-api/node_modules/rxjs/src/internal/Observable.ts:221:5) at /Users/champerwu/Documents/Project/naos-fin-interview/naos-api/node_modules/rxjs/src/internal/lastValueFrom.ts:59:12) at new Promise (<anonymous>)
解答
不是必须传递业务参数,但必须显式传递一个google.protobuf.Empty类型的空实例作为请求参数,原因如下:
- gRPC的底层客户端(
@grpc/grpc-js)对Unary方法有参数校验要求,即使请求类型是Empty,也必须传入该类型的实例,不能省略参数,否则会触发Incorrect arguments passed错误。 - 你的问题出在
ContractServiceClient接口定义上,接口里的getAllContractAddress()没有定义参数,但实际gRPC生成的客户端方法需要接收一个Empty实例。
修复步骤
导入
Empty类型:可以从google-protobuf包直接导入,或者使用NestJS代码生成工具生成的对应类型文件:import { Empty } from 'google-protobuf'; // 或者从自动生成的proto类型文件导入,比如: // import { Empty } from './proto/contractAddress';修正接口定义:给方法添加
Empty类型的参数:import { Observable } from 'rxjs'; import { Empty } from 'google-protobuf'; import { GetAllContractAddressResponse } from './path-to-your-types'; export interface ContractServiceClient { getAllContractAddress(request: Empty): Observable<GetAllContractAddressResponse>; }控制器调用时传入空实例:
@Get() getContractAddres() { return this.svc.getAllContractAddress(new Empty()); }
这样修改后,就能正常调用不需要业务参数的gRPC接口了。
内容的提问来源于stack exchange,提问作者Champer Wu
相关产品推荐
相关产品推荐

