Skip to content
文档
Handle Proto

Handle Proto

有时候,我们需要得到处理 proto 内容的能力,gRPCity库就提供了这样的能力,同时这些能力中在内部也会被调用。 例如: add(serviceName, implementation),就需要获取 proto 文件里定义的 service name

加载 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

有些场景,我们需要对 proto 的包名进行前缀补充,使用下面的方式:

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

使用了packagePrefix,在加载后会修改 proto 定义,所有的 path 都会有这个前缀。

service(name)

name参数,指 proto 文件路由,具体是到 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 文件的路由,包名到 service ,或到 model ,或到 messagetype() 的能力包含了 service()

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]
    }
  }
}