a7-plugin-grpc-transcode

star 1

Skill for configuring the API7 Enterprise Edition (API7 EE) grpc-transcode plugin via the a7 CLI. Covers converting RESTful HTTP requests to gRPC, proto file management, pb_option settings for data type conversion, error detail decoding, and gateway group scoping.

api7 By api7 schedule Updated 5/12/2026

name: a7-plugin-grpc-transcode description: >- Skill for configuring the API7 Enterprise Edition (API7 EE) grpc-transcode plugin via the a7 CLI. Covers converting RESTful HTTP requests to gRPC, proto file management, pb_option settings for data type conversion, error detail decoding, and gateway group scoping. version: "1.0.0" author: API7.ai Contributors license: Apache-2.0 metadata: category: plugin apisix_version: ">=3.0.0" plugin_name: grpc-transcode a7_commands: - a7 proto create - a7 proto list - a7 proto get - a7 proto delete - a7 route create - a7 route update - a7 route get


a7-plugin-grpc-transcode

Overview

The grpc-transcode plugin converts HTTP/JSON requests into gRPC calls and returns gRPC responses as JSON. Clients send standard HTTP requests; API7 EE transcodes them to gRPC using a pre-uploaded protobuf definition, forwards to the gRPC upstream, and returns the response as JSON. The gRPC service needs no modification.

When to Use

  • Expose gRPC services via RESTful HTTP endpoints
  • Allow browser/mobile clients to call gRPC services without gRPC client libraries
  • Add HTTP API gateway features (auth, rate limiting, logging) to gRPC services
  • Migrate from REST to gRPC incrementally
  • Decode gRPC error details into human-readable JSON

Plugin Configuration Reference (Route/Service)

Field Type Required Default Description
proto_id string/integer Yes ID of the proto resource (uploaded via a7 proto create).
service string Yes Fully qualified gRPC service name (e.g., helloworld.Greeter).
method string Yes gRPC method name (e.g., SayHello).
deadline number No 0 Deadline for the gRPC call in milliseconds. 0 = no deadline.
pb_option array[string] No Protobuf serialization options (see table below).
show_status_in_body boolean No false Include parsed grpc-status-details-bin in the JSON response body on errors.
status_detail_type string No Message type for the details field in gRPC error status. Required to decode error details.

pb_option Values

Option Description
enum_as_name Return enum fields as string names (e.g., "PENDING")
enum_as_value Return enum fields as integer values (e.g., 1)
int64_as_number Return int64 as JSON number (may lose precision in JavaScript)
int64_as_string Return int64 as string (safe for JavaScript clients)
int64_as_hexstring Return int64 as hexadecimal string
auto_default_values Auto-populate default values for unset fields
no_default_values Do not add default values for unset fields
use_default_values Use proto-defined default values

Multiple options can be combined: ["int64_as_string", "enum_as_name"]

Step-by-Step: Set Up gRPC Transcoding

1. Upload the proto definition

Upload it for gateway group 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. Create a route with 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

Critical: The upstream scheme must be "grpc" (or "grpcs" for TLS).

3. Test the endpoint

# Pass parameters via query string
curl "http://localhost:9080/grpc/hello?name=world"
# Response: {"message":"Hello world"}

# Or via POST body
curl -X POST http://localhost:9080/grpc/hello \
  -H "Content-Type: application/json" \
  -d '{"name": "world"}'

Common Patterns

Proto with imports (use compiled .pb file)

When your proto has import statements, compile to a .pb file first:

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

Then upload the base64-encoded .pb to gateway group prod:

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

Safe int64 handling for JavaScript clients

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

gRPC error detail decoding

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

Timeout control with deadline

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

Troubleshooting

Symptom Cause Fix
"can not find proto" Proto ID doesn't exist Verify with a7 proto get <id>
"method not found" Service or method name mismatch Use fully qualified name: package.Service, case-sensitive
Connection refused to upstream Wrong scheme or port Set upstream scheme to grpc, verify port is gRPC port
Import errors in proto Proto has imports but raw content uploaded Compile to .pb with protoc --include_imports
int64 values corrupted JavaScript precision loss Use pb_option: ["int64_as_string"]
gRPC call times out silently No deadline set Set deadline in milliseconds
502 Bad Gateway gRPC service not running or not reachable Check gRPC service is up and port is accessible
Config not applied Wrong gateway group specified Ensure --gateway-group matches the desired cluster

Config Sync Example

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
Install via CLI
npx skills add https://github.com/api7/a7 --skill a7-plugin-grpc-transcode
Repository Details
star Stars 1
call_split Forks 0
navigation Branch main
article Path SKILL.md
More from Creator