Skip to Content
🎉 gRPCity 3.0 is released. Read more →
文档高级功能Handle Proto

Handle Proto

loader 内置了一组用于直接观察解析后 proto 内容的低层 helper。它们与 gRPCity 内部 add(serviceName, impl) 一类的实现共用同一组原语——当你需要做服务自省、按全限定名查 message、或者对一棵已加载的 proto 树写工具时会用到。

加载 proto

protos/test/helloworld/ 当 proto 根目录,内容如下:

protos/test/helloworld/helloworld.proto
service Greeter { // Sends a greeting rpc SayHello(model.HelloRequest) returns (model.HelloReply) {} rpc SayHello2(model.HelloRequest) returns (model.HelloReply) {} }

我们需要先完成 proto 的加载。

import { ProtoLoader } from 'grpcity' import path from 'node:path' import { fileURLToPath } from 'node:url' const __dirname = path.dirname(fileURLToPath(import.meta.url)) const loader = new ProtoLoader({ location: path.resolve(__dirname, 'protos'), files: ['test/helloworld/helloworld.proto'] }) (async () => { await loader.init() })()

Package prefix

需要给已加载的定义加命名空间——通常用于租户或环境隔离——给 init()isDevpackagePrefix

await loader.init({ isDev: true, packagePrefix: 'stage.dev' })

设置了 prefix 之后,加载到的所有定义——包括 wire 上的方法路径——都会带上它。服务端和客户端必须配同一个 prefix。

service(name)

name.proto 中含包名的完整 service 名称,返回值是底层的 gRPC service 定义。

const serviceDefinition = loader.service('test.helloworld.Greeter') console.log(serviceDefinition)

打印结果:

Terminal
{ SayHello: { path: '/stage.dev.test.helloworld.Greeter/SayHello', requestStream: false, responseStream: false, requestSerialize: [Function: serialize], requestDeserialize: [Function: deserialize], responseSerialize: [Function: serialize], responseDeserialize: [Function: deserialize], originalName: 'sayHello', requestType: { format: 'Protocol Buffer 3 DescriptorProto', type: [Object], fileDescriptorProtos: [Array] }, responseType: { format: 'Protocol Buffer 3 DescriptorProto', type: [Object], fileDescriptorProtos: [Array] } }, SayHello2: { path: '/stage.dev.test.helloworld.Greeter/SayHello2', requestStream: false, responseStream: false, requestSerialize: [Function: serialize], requestDeserialize: [Function: deserialize], responseSerialize: [Function: serialize], responseDeserialize: [Function: deserialize], originalName: 'sayHello2', requestType: { format: 'Protocol Buffer 3 DescriptorProto', type: [Object], fileDescriptorProtos: [Array] }, responseType: { format: 'Protocol Buffer 3 DescriptorProto', type: [Object], fileDescriptorProtos: [Array] } } }

type(name)

name 是已加载 proto 树里任意全限定名——package、service、model 或 message。type()service() 的超集:能传给 service() 的,type() 也都能解析。

type('test') 例子:

const typePkg = loader.type('test') console.log(typePkg)

打印结果:

Terminal
{ helloworld: { Greeter: [class ServiceClientImpl extends Client] { service: [Object], serviceName: 'Greeter' }, Hellor: [class ServiceClientImpl extends Client] { service: [Object], serviceName: 'Hellor' }, model: { HelloRequest: [Object], HelloReply: [Object] } } }

type('test.helloworld') 例子:

const typePkg = loader.type('test.helloworld') console.log(typePkg)

打印结果:

Terminal
{ Greeter: [class ServiceClientImpl extends Client] { service: { SayHello: [Object], SayHello2: [Object] }, serviceName: 'Greeter' }, Hellor: [class ServiceClientImpl extends Client] { service: { SayHello: [Object], SayHello2: [Object] }, serviceName: 'Hellor' }, model: { HelloRequest: { format: 'Protocol Buffer 3 DescriptorProto', type: [Object], fileDescriptorProtos: [Array] }, HelloReply: { format: 'Protocol Buffer 3 DescriptorProto', type: [Object], fileDescriptorProtos: [Array] } } }
Last updated on