API7 Docs

grpc-transcode plugin for API7 Gateway

Skill for configuring the API7 Enterprise Edition (API7 EE) grpc-transcode plugin via the a7 CLI. Covers converting RESTful HTTP requests to gRPC, proto…

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)

FieldTypeRequiredDefaultDescription
proto_idstring/integerYesID of the proto resource (uploaded via a7 proto create).
servicestringYesFully qualified gRPC service name (e.g., helloworld.Greeter).
methodstringYesgRPC method name (e.g., SayHello).
deadlinenumberNo0Deadline for the gRPC call in milliseconds. 0 = no deadline.
pb_optionarray[string]NoProtobuf serialization options (see table below).
show_status_in_bodybooleanNofalseInclude parsed grpc-status-details-bin in the JSON response body on errors.
status_detail_typestringNoMessage type for the details field in gRPC error status. Required to decode error details.

pb_option Values

OptionDescription
enum_as_nameReturn enum fields as string names (e.g., "PENDING")
enum_as_valueReturn enum fields as integer values (e.g., 1)
int64_as_numberReturn int64 as JSON number (may lose precision in JavaScript)
int64_as_stringReturn int64 as string (safe for JavaScript clients)
int64_as_hexstringReturn int64 as hexadecimal string
auto_default_valuesAuto-populate default values for unset fields
no_default_valuesDo not add default values for unset fields
use_default_valuesUse 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

SymptomCauseFix
"can not find proto"Proto ID doesn't existVerify with a7 proto get <id>
"method not found"Service or method name mismatchUse fully qualified name: package.Service, case-sensitive
Connection refused to upstreamWrong scheme or portSet upstream scheme to grpc, verify port is gRPC port
Import errors in protoProto has imports but raw content uploadedCompile to .pb with protoc --include_imports
int64 values corruptedJavaScript precision lossUse pb_option: ["int64_as_string"]
gRPC call times out silentlyNo deadline setSet deadline in milliseconds
502 Bad GatewaygRPC service not running or not reachableCheck gRPC service is up and port is accessible
Config not appliedWrong gateway group specifiedEnsure --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

This page is generated from a7-plugin-grpc-transcode/SKILL.md in the api7/a7 repository. Browse all skills on the AI Agent Skills page.