Skip to content

HTTP/JSON

The HTTP/JSON surface comes from grpc-gateway: routes and payload shapes are generated from google.api.http annotations in the proto. No handlers are written by hand.

Annotations sit on each rpc, for example in the sample resource:

rpc GetResource(GetResourceRequest) returns (Resource) {
option (google.api.http) = {get: "/v1/resources/{id}"};
}

The full mapping for the sample resource:

RPC HTTP
CreateResource POST /v1/resources
GetResource GET /v1/resources/{id}
ListResources GET /v1/resources
UpdateResource PATCH /v1/resources/{id}
DeleteResource DELETE /v1/resources/{id}
Terminal window
curl localhost:8080/v1/resources/x \
-H 'Authorization: Bearer <token>'

Without a token the response is 401. The gateway shares the interceptor chain with gRPC and MCP, and error bodies come from the unified error model — internal causes are not included.

The gateway caps request bodies at 1 MiB with a 30-second read timeout: oversized bodies get 413, slow reads get 408.

  • server.enable_cors: true is only the master switch; the actual allowlist is server.cors_origins. Origins not listed there receive no CORS headers at all — enabling enable_cors without setting origins still blocks browsers. Use "*" to allow all, or list explicit origins (GORTEXA_SERVER__CORS_ORIGINS accepts a comma-separated override). Preflight OPTIONS requests are short-circuited.
  • With server.openapi: true, the OpenAPI spec is served at /openapi.json. The spec is a build artifact of make gen, read once at startup from gen/openapiv2/gortexa.swagger.json, relative to the working directory, and served from memory. When that file is missing, /openapi.json answers 404 openapi spec unavailable. A container image that needs the endpoint must ship the file at that path under its WORKDIR.

The gateway forwards Authorization and X-Request-Id onto fixed metadata keys and refuses any Grpc-Metadata-* header that would collide with a trusted key (authorization, x-request-id, x-gortexa-peer-ip) — a client cannot smuggle a second value onto its own token, request id or rate-limit identity. Separately, Authorization, X-Forwarded-For and X-Forwarded-Host are the three headers grpc-gateway splices into outgoing metadata without a validity check of its own, so the gateway filters them: any value outside printable ASCII is dropped rather than forwarded. Left in place, one such byte would make the loopback fail with internal before the interceptor chain ran, handing the caller an opaque 500 with no request id instead of the chain’s real verdict — and letting an anonymous caller drive the server’s internal-error rate.

Response headers pass through an allowlist: internal headers do not leak, and X-Request-Id is preserved for correlation.