A gRPC upstream
GuideOperationsSince version 1.1.0
Operations guide: configure, deploy and observe the gateway. What the capability does, product side: product guide; calling it: developer guide.
Goal: serve a gRPC service to gRPC clients, to a browser (gRPC-Web) and in REST/JSON, from its
.proto alone.
Command - the upstream's team annotates its .proto: the standard REST mapping
(google.api.http) and what Flexway needs beyond it (flexway.v1.operation, the counterpart of
x-flexway-*). Then it builds the descriptor set:
syntax = "proto3";
package shop.v1; // the gRPC name is shop.v1.Orders/GetOrder
import "flexway/v1/options.proto"; // copy it from the tag you run: services/gateway/api/flexway/v1/options.proto
import "google/api/annotations.proto"; // from buf.build/googleapis/googleapis, below
service Orders {
rpc GetOrder(GetOrderRequest) returns (Order) {
option (google.api.http) = { get: "/v1/shop/orders/{id}" };
option (flexway.v1.operation) = { upstream: "orders" security: [ { scopes: ["orders:read"] } ] };
}
}v=<version> # the Flexway you run
mkdir -p flexway/v1 && curl -fsSLo flexway/v1/options.proto \
"https://raw.githubusercontent.com/flexwiz/flexway/v$v/services/gateway/api/flexway/v1/options.proto"
cat > buf.yaml <<'YAML'
version: v2
deps: [buf.build/googleapis/googleapis]
YAML
buf dep update
buf build -o orders.binpb # or: protoc --include_imports --descriptor_set_out=orders.binpb ...contracts:
protobuf: [./orders.binpb]
upstreams:
orders: { url: http://orders.internal:9000, protocol: grpc } # h2c inside a meshCheck:
grpcurl -plaintext -protoset orders.binpb -H "authorization: Bearer $TOKEN" \
-d '{"id":"42"}' localhost:8080 shop.v1.Orders/GetOrder # gRPC, on the traffic port
curl -H "authorization: Bearer $TOKEN" localhost:8080/v1/shop/orders/42 # the same operation in RESTBoth calls are one operation, shop.v1.Orders/GetOrder: same identity, same rate, same quota,
same audit line. A refusal reaches a gRPC client as a google.rpc.Status (the problem code in
ErrorInfo.reason), a REST client as RFC 9457. An error of the upstream reaches a REST client as an
upstream_status problem, its gRPC status in the grpc extension. A server stream is a
text/event-stream in REST.
For a browser (gRPC-Web), the
corspolicy exposesgrpc-status,grpc-messageandgrpc-status-details-bin(expose_headers) and acceptsx-grpc-web,x-user-agentandgrpc-timeout(allow_headers): without them, the browser cannot read a refusal. Refused at load at this version: a variable spanning segments ({name=shelves/*}), a wildcard, a verb (:cancel),google.api.httpon a client or bidirectional stream - those stay served in gRPC only.