Loader
我们使用 Proto Loader 的时候,只需要在创建实例的时候,传入参数即可。
import { ProtoLoader } from 'grpcity'
const loader = new ProtoLoader({ location, files })
为什么传参是location
和files
?
location
是指 proto 文件目录,包含 service 引用的 proto,如model.proto
、empty.proto
等等这些被独立引用的文件。files
是指具体的service.proto
文件,告诉底层 service 的定义来自这些文件,是具体的服务定义。
带来的好处:
- service 加载非常清晰,知道是哪些 service 会被使用
- proto 的目录结构,可以自定义,不影响加载
目录获取
ESM 模块的代码文件目录获取如下:
import { ProtoLoader } from 'grpcity'
import path from 'node:path'
import { fileURLToPath } from 'node:url'
// __dirname for esm
const __dirname = path.dirname(fileURLToPath(import.meta.url))
如果是 CommonJS 模块的代码只 __dirname
是全局的,只需要在需要用到的地方直接使用即可。
单个目录加载
大多数情况下,我们只需要加载一次proto目录,并指定多个service,如下所示:
export default new ProtoLoader({
location: path.join(__dirname, './proto'),
files: [
'path/to/service-a.proto',
'path/to/service-b.proto'
]
})
多个目录加载
有时候,我们需要跨业务进行服务调用,这个时候就会出现多个proto目录都需要加载的情况,
我们的gRPCity
已经做好了这块的多proto目录的加载支持了。如下所示:
export default new ProtoLoader([
{
location: path.join(__dirname, './proto1'),
files: [
'path/to/service-a.proto'
]
},
{
location: path.join(__dirname, './proto2'),
files: [
'path/to/service-b.proto'
]
},
])
初始化 init()
为什么 loader 还需要 init ?
init
是真正把proto加载的执行。同时也是自定义参数和环境的配置位置,功能更加独立,可以放到服务框架流程中的第一步,只需要执行一次。
await loader.init(options)
options
说明,包含如下参数:
- isDev: (可选)布尔值,是否为开发模式;
- packagePrefix: (可选)字符串,service name 包前缀,如:
dev
,stage
等等; - loadOptions: (可选)proto load options;
💡
其中loadOptions
更多说明请看这一篇: Config
示例
注意使用了packagePrefix
之后,服务端和客户端都要一致。
test 环境,配置如下:
await loader.init({
isDev: true,
packagePrefix: 'test'
})
stage 环境,配置如下:
await loader.init({
isDev: true,
packagePrefix: 'stage'
})
production 环境,直接忽略掉这两个配置项即可,如下:
await loader.init()