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() 传 isDev 与 packagePrefix:
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