Expose a gRPC service
Octopus proxies gRPC transparently over HTTP/2. It does not parse your
.proto files — it forwards the gRPC framing, metadata, and trailers between the
client and the upstream. A gRPC upstream is therefore just an HTTP/2 upstream,
and a gRPC route is just a normal route whose path is the gRPC service. There is
no protocol flag: a request is treated as gRPC when its Content-Type begins
with application/grpc.
The upstream connection is plaintext HTTP/2 (h2c) — the gateway opens a TCP connection and performs an HTTP/2 handshake directly. Your gRPC server must accept h2c (no TLS between gateway and upstream).
Point a route at your gRPC upstream01
Declare the backend as an upstream and add a route whose path is the fully
qualified service, /{package.Service}. gRPC calls are HTTP/2 POSTs to
/{package.Service}/{Method}, so a path of /users.UserService matches every
method on that service.
upstreams:
- name: users-grpc
instances:
- id: users-grpc-1
host: 127.0.0.1
port: 50051
routes:
- path: /users.UserService
upstream: users-grpcThe router resolves the upstream from the request host and the gRPC path exactly like an HTTP route. To proxy several services, add one route per service.
(Optional) Acknowledge the gRPC config block02
A top-level grpc block exists. You can include it for documentation, but be
aware of its current status.
grpc:
enabled: true
deadline_propagation: trueIn the current build the live gRPC proxy path does not read this block — it
uses built-in defaults, routes via the normal router (not the services map),
and always propagates grpc-timeout when present. So enable_reflection,
enable_grpc_web, max_message_size, and services are parsed but not yet
wired into the proxy. The block is safe to omit entirely; deadline
propagation happens regardless. See gRPC configuration.
Validate and run03
octopus validate -c gateway.yaml
octopus serve -c gateway.yamlThe complete, validated configuration:
gateway:
listen: "0.0.0.0:8080"
grpc:
enabled: true
deadline_propagation: true
upstreams:
- name: users-grpc
instances:
- id: users-grpc-1
host: 127.0.0.1
port: 50051
routes:
- path: /users.UserService
upstream: users-grpcCall it04
Use any gRPC client through the gateway. Deadlines propagate: a grpc-timeout
header on the request becomes the upstream call timeout (default 30s when
absent), and authorization/grpc-* metadata passes straight through.
# grpcurl, plaintext, through the gateway on :8080
grpcurl -plaintext \
-d '{"id": "42"}' \
localhost:8080 users.UserService/GetUserIf the upstream cannot be reached the gateway returns gRPC UNAVAILABLE; on
timeout it returns DEADLINE_EXCEEDED (as HTTP 200 with the gRPC status in
trailers, per the gRPC spec).
Known limitations05
These are properties of the current transparent proxy — see Protocols → gRPC for the details:
Unary and server-streaming work. Client-streaming and bidirectional streaming are buffered on the request side, not truly streamed, because the request body is collected in full before forwarding.
No reflection proxy and no JSON↔gRPC transcoding.
gRPC-Web content types are detected but not translated in the proxy path.
Plaintext (h2c) upstream only — no TLS to the upstream.
See also06
Protocols → gRPC — how detection, forwarding, and deadlines work.
gRPC configuration — the
grpcblock (currently display-only).Route with the Gateway API —
GRPCRouteon Kubernetes.