ToolJet gRPC 数据源接入实战:Proto 文件挂载、连接认证与 RPC 查询
【免费下载链接】ToolJetOpen-source foundation of ToolJet AI - the enterprise app generation platform for internal tools, dashboards, business applications, workflows and AI agents. Build visually, from a prompt, or from Claude Code, Codex and Cursor over MCP 🚀项目地址: https://gitcode.com/GitHub_Trending/to/ToolJet
本指南基于 ToolJet 3.0.0-LTS 版本文档,完整讲解如何在**自托管(Self-hosted)**部署中启用 gRPC 数据源:从升级版本、放置 proto 文件、挂载 Docker 卷到建立连接并查询 RPC 方法。读者将掌握 gRPC 数据源的全流程配置,并理解其底层基于@grpc/grpc-js与@grpc/proto-loader的实现原理,能够直接在自有 ToolJet 实例中接入任何基于 Protocol Buffers 定义的 gRPC 服务。
适用前提:gRPC 数据源仅适用于自托管部署,且当前版本仅支持一元请求(unary)与响应(即一请求一响应的普通 RPC 调用,不包含流式 RPC)。
Setup:在自托管实例中启用 gRPC 数据源
Step 1: 将 ToolJet 升级到 2.5 及以上版本
gRPC 数据源依赖自托管部署的插件系统与 proto 文件加载机制,因此需要先将实例升级到ToolJet 2.5 或更高版本。升级操作请参考 ToolJet 安装与升级指南,不同部署方式(Docker Compose、Kubernetes、Helm 等)的升级路径略有差异,请按你当前的部署方式操作。
Step 2: 添加 Proto 文件
gRPC 服务的接口定义依赖.proto文件。ToolJet 约定在项目根目录下创建名为protos的目录,并在其中放置名为service.proto的文件:
<部署根目录>/ └── protos/ └── service.proto该文件名与路径是硬编码约定:从源码看,gRPC 插件实现 通过以下逻辑定位 proto 文件:
const cwd = process.cwd(); const rootDir = cwd.split('/').slice(0, -1).join('/'); const protoFilePath = `${rootDir}/protos/service.proto`;即插件以当前工作目录的上一级目录为根,固定拼接protos/service.proto。因此 proto 文件必须命名为service.proto,且位于部署根目录的protos/下,插件才能正确加载。service.proto中应包含你的 gRPC 服务定义,例如:
syntax = "proto3"; package password; service PasswordService { rpc RetrievePasswords (RetrieveRequest) returns (RetrieveResponse); rpc AddNewDetails (AddRequest) returns (AddResponse); rpc UpdatePasswordDetails (UpdateRequest) returns (UpdateResponse); } message RetrieveRequest { string query = 1; } message RetrieveResponse { repeated PasswordRecord passwords = 1; } // ... 其余 message 定义Step 3: 挂载卷(Volumes)
在docker-compose.yml中,为plugins和server两个服务的volumes部分分别添加以下挂载项,使容器内能访问宿主机的 proto 文件:
./protos:/app/protos以当前仓库根目录的 docker-compose.yaml 为例,plugins与server服务均会挂载本地源码目录:
plugins: ... volumes: - ./plugins:/app/plugins - ./protos:/app/protos # ← 新增此行 server: ... volumes: - ./server:/app/server:delegated - ./plugins:/app/plugins - ./protos:/app/protos # ← 新增此行 - /app/server/node_modules/挂载完成后,容器内plugins与server进程均能在/app/protos下找到service.proto,从而保证插件运行时可以读取到服务定义。
Step 4: 重启实例
修改完docker-compose.yml并放置好 proto 文件后,重新创建并启动容器:
docker-compose up -d重启后,插件服务会重新加载,此时 gRPC 数据源即可在全局数据源页面中使用。
Querying gRPC:连接与查询
完成上述设置后,前往**全局数据源(Global Datasource)**页面建立 gRPC 连接,参见 数据源总览 了解全局数据源的工作方式:连接一旦在工作区建立,即可被该工作区的任意应用共享复用。
连接 gRPC 数据源
在数据源列表中选择 gRPC,ToolJet 要求填写以下连接信息:
| 配置项 | 说明 |
|---|---|
| Server URL | gRPC 服务器地址,格式为host:port,例如0.0.0.0:50051(必填项) |
| Authentication type | 认证类型,可选值如下 |
**认证类型(Authentication type)**支持四种模式:
- None:无认证(默认值)
- Basic:基础认证,需要用户名与密码
- Bearer:Bearer Token 认证,需要令牌
- API key:API 密钥认证,需要密钥名与密钥值
连接参数的底层实现
从数据源的清单文件 manifest.json 可以确认:url是唯一必填项("required": ["url"]),auth_type的默认值为none,而password、bearer_token、grpc_apikey_value等敏感字段均标记为"encrypted": true,说明这些凭据在存储层会做加密处理。
认证逻辑在插件核心实现 index.ts 中,通过向 gRPC 请求的Metadata(元数据)注入认证信息完成:
const authType = sourceOptions.auth_type || 'none'; const metadata = new grpc.Metadata(); if (authType === 'basic') { metadata.add('username', sourceOptions.username); metadata.add('password', sourceOptions.password); } if (authType === 'bearer') { metadata.add('Authorization', `Bearer ${sourceOptions.bearer_token}`); } if (authType === 'api_key') { metadata.add(sourceOptions.grpc_apikey_key, sourceOptions.grpc_apikey_value); }可以看到:Basic 认证会以username/password作为元数据键值对发送;Bearer 认证拼接Authorization: Bearer <token>头;API key 则将用户自定义的密钥名与密钥值作为一对元数据发送。这些元数据最终由@grpc/grpc-js客户端随请求一同发送到服务端。
客户端创建与 proto 加载
连接建立后,插件使用@grpc/proto-loader同步加载service.proto,再用@grpc/grpc-js构造客户端桩(client stub):
const options: protoLoader.Options = { keepCase: true, longs: String, enums: String, defaults: true, oneofs: true, }; const grpcObj: any = protoLoader.loadSync(protoFilePath, options); const Service: any = grpc.loadPackageDefinition(grpcObj)[serviceName]; const clientStub: any = new Service(sourceOptions.url, grpc.credentials.createInsecure());关键点说明:
keepCase: true保留字段原始大小写;longs/enums转为字符串;defaults: true为缺失字段填充默认值;oneofs: true支持 oneof 语义;- 当前实现使用
grpc.credentials.createInsecure()建立明文通道,即不启用 TLS; - 服务名(
serviceName)来自loadPackageDefinition返回的包对象,因此service.proto中声明的 package 与 service 名称必须与你在查询时选择的服务名一致。
创建查询
在全局数据源页面添加 gRPC 数据源后,它就会出现在应用的**查询面板(Query Panel)**的可用数据源列表中。你可以针对已添加服务中的任意RPC 方法创建查询。
创建查询时需要提供:
| 查询参数 | 说明 |
|---|---|
| Service | 从 proto 文件中解析出的服务名,如PasswordService |
| RPC 方法 | 该服务下可调用的方法,如RetrievePasswords、AddNewDetails |
| Message(请求体) | 以 JSON 形式填写请求消息内容 |
查询执行链路
查询执行的核心逻辑见 index.ts:请求消息体以 JSON 字符串形式传入,插件先做解析:
let jsonMessage = {}; if (queryOptions.jsonMessage) { try { jsonMessage = JSON.parse(queryOptions.jsonMessage); } catch (e) { throw new QueryError('Invalid JSON message', {}, {}); } }若消息体不是合法 JSON,会直接抛出Invalid JSON message错误。解析成功后,插件调用客户端桩上对应的方法并携带元数据发起调用:
const result = await new Promise((resolve, reject) => { clientStubrpc => { if (err) { reject(err); } resolve(response); }); }).catch((err) => { throw new QueryError(err.message, {}, {}); }); return { status: 'ok', data: result as any, };调用成功后,响应数据会以data字段返回,同时插件暴露isLoading、data、rawData三个变量供应用前端绑定使用(见 manifest.json 中的exposedVariables)。查询失败时,gRPC 返回的错误消息会包装为QueryError传递到查询面板,便于定位问题。
进阶:gRPC 2.0 数据源(Server Reflection 与 TLS)
仓库中还包含功能更完整的gRPC 2.0插件(grpcv2 实现),它在原版基础上提供了三种 proto 来源方式(见其 manifest.json):
- server_reflection(默认):通过 gRPC Server Reflection 协议自动发现服务与方法,无需手动放置 proto 文件;
- import_proto_file:从远程 URL 导入单个
.proto文件; - import_protos_from_filesystem:从文件系统目录(默认 glob 模式
**/*.proto)导入 proto 文件,并在配置页通过listServices动态发现服务列表。
同时支持 SSL/TLS 传输层加密(CA 证书、客户端证书)、OAuth2 授权码认证以及自定义 Metadata 头。如果你的 gRPC 服务支持 Server Reflection 或需要 TLS,可以优先评估使用 gRPC 2.0 数据源;本文档所述的原版 gRPC 数据源则对应上述自托管 + proto 挂载 + 一元调用的经典场景。
常见问题排查
- 查询报
Missing URL:Server URL为空,连接配置未保存完整,请检查全局数据源页面是否已填写并保存。 - 查询报
Invalid JSON message:查询面板中填写的请求消息体不是合法 JSON,请用 JSON 格式(而非 protobuf 文本格式)书写。 - 找不到服务或方法:确认
protos/service.proto已放置在部署根目录下、docker-compose.yml已正确挂载卷并重启;同时核对 proto 中 service 名称与查询面板所选服务名一致。 - 连接被拒绝:确认 gRPC 服务器地址
host:port可达,且服务端监听端口与 Server URL 一致;原版 gRPC 数据源走明文通道,请确认服务端未强制要求 TLS。
小结
gRPC 数据源让 ToolJet 应用能够直接调用基于 Protocol Buffers 定义的远程过程调用服务,其接入路径可概括为:升级版本 → 放置protos/service.proto→ 为 plugins 与 server 挂载卷 → 重启 → 全局数据源配置连接 → 查询面板发起 RPC 调用。底层由@grpc/grpc-js与@grpc/proto-loader驱动,认证信息通过 Metadata 注入,请求消息以 JSON 形式解析后映射为 protobuf 消息。相关源码与配置均可在仓库的 plugins/packages/grpc 目录中进一步查阅。
【免费下载链接】ToolJetOpen-source foundation of ToolJet AI - the enterprise app generation platform for internal tools, dashboards, business applications, workflows and AI agents. Build visually, from a prompt, or from Claude Code, Codex and Cursor over MCP 🚀项目地址: https://gitcode.com/GitHub_Trending/to/ToolJet
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考