GRPC
GRPC
该 GRPC 是一个高性能的,开源的通用RPC框架。
安装
在我们开始之前,我们必须安装所需的包:
$ npm i --save grpc @grpc/proto-loader
运输车
为了切换到gRPC
传输器,我们需要修改传递给该createMicroservice()
方法的选项对象。
main.ts
JS
const app = await NestFactory.createMicroservice(ApplicationModule, {
transport: Transport.GRPC,
options: {
package: 'hero',
protoPath: join(__dirname, 'hero/hero.proto'),
},
}
提示
该join()
功能从path
包中导入。
选项
有许多可用的选项可以确定转运行为。
url | 连接网址 |
---|---|
protoPath | 绝对(或相对于根目录).proto文件的路径 |
loader | @grpc/proto-loader选项。它们在这里有很好的描述。 |
package | Protobuf包名 |
credentials | 服务器凭证(了解更多) |
概观
通常,package
属性设置protobuf
包名称,而定义文件protoPath
的路径.proto
。该hero.proto
文件使用协议缓冲区语言构建。
hero.proto
syntax = "proto3";
package hero;
service HeroService {
rpc FindOne (HeroById) returns (Hero) {}
}
message HeroById {
int32 id = 1;
}
message Hero {
int32 id = 1;
string name = 2;
}
在上面的例子中,我们定义了一个HeroService
公开一个FindOne()
gRPC处理程序,它希望HeroById
作为一个输入并返回一个Hero
消息。为了定义一个满足这个protobuf定义的处理程序,我们必须使用一个@GrpcMethod()
装饰器。先前已知@MessagePattern()
的不再有用。
hero.controller.ts
JS
@GrpcMethod('HeroService', 'FindOne')
findOne(data: HeroById, metadata: any): Hero {
const items = [
{ id: 1, name: 'John' },
{ id: 2, name: 'Doe' },
];
return items.find({ id }) => id === data.id
}
提示
该@GrpcMethod()
装饰器从进口@nestjs/microservices
包。
这HeroService
是服务的名称,同时FindOne
指向FindOne()
gRPC处理程序。相应的findOne()
方法有两个参数,data
从调用者传递并metadata
存储gRPC请求的元数据。
此外,FindOne这里实际上是多余的。如果没有传递第二个参数@GrpcMethod(),Nest将自动使用带有大写首字母的方法名称,例如findOne- > FindOne。
hero.controller.ts
JS
@GrpcMethod('HeroService')
findOne(data: HeroById, metadata: any): Hero {
const items = [
{ id: 1, name: 'John' },
{ id: 2, name: 'Doe' },
];
return items.find({ id }) => id === data.id
}
同样,您可能不会传递任何参数。在这种情况下,Nest将使用类名。
hero.controller.ts
JS
@Controller()
export class HeroService {
@GrpcMethod()
findOne(data: HeroById, metadata: any): Hero {
const items = [
{ id: 1, name: 'John' },
{ id: 2, name: 'Doe' },
];
return items.find({ id }) => id === data.id
}
}
客户
为了创建客户端实例,我们需要使用@Client()
装饰器。
hero.controller.ts
JS
@Client{
transport: Transport.GRPC,
options: {
package: 'hero',
protoPath: join(__dirname, 'hero/hero.proto'),
},
})
private readonly client: ClientGrpc;
与前面的例子相比有一点不同。ClientProxy
我们使用ClientGrpc
提供getService()
方法的方法而不是类。该getService()
通用方法以服务的名称作为参数,如果有返回它的实例。
hero.controller.ts
JS
onModuleInit() {
this.heroService = this.client.getService<HeroService>('HeroService'
}
该heroService
对象公开了在.proto
文件中定义的同一组方法。注意,所有这些都是小写的
(为了遵循自然惯例)。基本上,我们的gRPC HeroService
定义包含FindOne()
函数。这意味着heroService
实例将提供该findOne()
方法。
interface HeroService {
findOne(data: { id: number }): Observable<any>;
}
所有服务的方法都返回Observable
。由于Nest支持 RxJS 流并且可以很好地与它们配合使用,因此我们也可以在HTTP处理程序中返回它们。
hero.controller.ts
JS
@Get()
call(): Observable<any> {
return this.heroService.findOne{ id: 1 }
}