跳到主要内容
版本:3.10.x

API7 网关 AI Agent Skill:grpc-transcode 插件

概览

grpc-transcode 插件会将 HTTP/JSON 请求转换为 gRPC 调用,并将 gRPC 响应返回为 JSON。客户端发送标准 HTTP 请求,API7 企业版使用预先上传的 protobuf 定义将其转换为 gRPC 请求,转发到 gRPC 上游,再将响应返回为 JSON。gRPC 服务无需修改。

适用场景

  • 通过 RESTful HTTP 端点公开 gRPC 服务。
  • 允许浏览器或移动客户端在没有 gRPC 客户端库的情况下调用 gRPC 服务。
  • 为 gRPC 服务添加 HTTP API 网关功能(认证、限流、日志)。
  • 逐步从 REST 迁移到 gRPC。
  • 将 gRPC 错误详情解码为人类可读的 JSON。

插件配置参考(路由/服务)

字段类型是否必填默认值说明
proto_idstring/integerproto 资源 ID(通过 a7 proto create 上传)。
servicestring完全限定的 gRPC 服务名称(例如 helloworld.Greeter)。
methodstringgRPC 方法名称(例如 SayHello)。
deadlinenumber0gRPC 调用的截止时间,单位为毫秒。0 表示无截止时间。
pb_optionarray[string]Protobuf 序列化选项(见下表)。
show_status_in_bodybooleanfalse出错时将解析后的 grpc-status-details-bin 包含在 JSON 响应体中。
status_detail_typestringgRPC 错误状态中 details 字段的消息类型。解码错误详情时必须设置。

pb_option 值

选项说明
enum_as_name将枚举字段返回为字符串名称(例如 "PENDING"
enum_as_value将枚举字段返回为整数值(例如 1
int64_as_number将 int64 返回为 JSON 数字(JavaScript 中可能丢失精度)
int64_as_string将 int64 返回为字符串(适用于 JavaScript 客户端)
int64_as_hexstring将 int64 返回为十六进制字符串
auto_default_values为未设置的字段自动填充默认值
no_default_values不为未设置的字段添加默认值
use_default_values使用 proto 定义的默认值

多个选项可以组合使用:["int64_as_string", "enum_as_name"]

分步指南:设置 gRPC 转码

1. 上传 proto 定义

将其上传到 default 网关组:

a7 proto create --gateway-group default -f - <<'EOF'
{
"id": "1",
"content": "syntax = \"proto3\";\npackage helloworld;\nservice Greeter {\n rpc SayHello (HelloRequest) returns (HelloReply) {}\n}\nmessage HelloRequest {\n string name = 1;\n}\nmessage HelloReply {\n string message = 1;\n}"
}
EOF

2. 使用 grpc-transcode 创建路由

a7 route create --gateway-group default -f - <<'EOF'
{
"id": "grpc-hello",
"methods": ["GET", "POST"],
"uri": "/grpc/hello",
"plugins": {
"grpc-transcode": {
"proto_id": "1",
"service": "helloworld.Greeter",
"method": "SayHello"
}
},
"upstream": {
"scheme": "grpc",
"type": "roundrobin",
"nodes": [{"host": "grpc-server", "port": 50051, "weight": 1}]
}
}
EOF

**重要:**该上游的 scheme 必须"grpc"(使用 TLS 时为 "grpcs")。

3. 测试端点

# 通过查询字符串传递参数
curl "http://localhost:9080/grpc/hello?name=world"
# 响应:{"message":"Hello world"}

# 或通过 POST 请求体传递
curl -X POST http://localhost:9080/grpc/hello \
-H "Content-Type: application/json" \
-d '{"name": "world"}'

常见模式

Proto 使用 imports(使用已编译的 .pb 文件)

如果 proto 包含 import 语句,请先将其编译为 .pb 文件:

protoc --include_imports --descriptor_set_out=service.pb proto/service.proto

然后将 Base64 编码的 .pb 文件上传到 prod 网关组:

a7 proto create --gateway-group prod -f - <<EOF
{
"id": "2",
"content": "$(base64 -i service.pb)"
}
EOF

为 JavaScript 客户端安全处理 int64

{
"plugins": {
"grpc-transcode": {
"proto_id": "1",
"service": "order.OrderService",
"method": "GetOrder",
"pb_option": ["int64_as_string"]
}
}
}

gRPC 错误详情解码

{
"plugins": {
"grpc-transcode": {
"proto_id": "1",
"service": "helloworld.Greeter",
"method": "SayHello",
"show_status_in_body": true,
"status_detail_type": "helloworld.ErrorDetail"
}
}
}

使用 deadline 控制超时

{
"plugins": {
"grpc-transcode": {
"proto_id": "1",
"service": "slow.SlowService",
"method": "LongRunning",
"deadline": 5000
}
}
}

故障排查

现象原因解决方法
"can not find proto"proto ID 不存在使用 a7 proto get <id> 验证
"method not found"服务或方法名称不匹配使用完全限定名称:package.Service,并注意大小写
无法连接上游scheme 或端口错误将上游 scheme 设置为 grpc,并确认端口为 gRPC 端口
proto 导入错误proto 包含 imports,但上传了原始内容使用 protoc --include_imports 编译为 .pb
int64 值损坏JavaScript 精度丢失使用 pb_option: ["int64_as_string"]
gRPC 调用无提示超时未设置 deadlinedeadline 设置为毫秒数
502 Bad GatewaygRPC 服务未运行或无法访问检查 gRPC 服务和端口是否可用
配置未生效指定了错误的网关组确保 --gateway-group 与目标集群一致

配置同步示例

version: "1"
gateway_group: default
protos:
- id: helloworld-proto
content: |
syntax = "proto3";
package helloworld;
service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
message HelloRequest {
string name = 1;
}
message HelloReply {
string message = 1;
}
routes:
- id: grpc-hello
methods:
- GET
- POST
uri: /grpc/hello
plugins:
grpc-transcode:
proto_id: helloworld-proto
service: helloworld.Greeter
method: SayHello
pb_option:
- int64_as_string
- enum_as_name
upstream:
scheme: grpc
type: roundrobin
nodes:
- host: grpc-server
port: 50051
weight: 1

本页面由 api7/a7 仓库中的 a7-plugin-grpc-transcode/SKILL.md 生成。你可以在 AI Agent Skills 页面查看所有技能。