跳到內容

HTTP/JSON

HTTP/JSON 介面由 grpc-gateway 提供:路由與 payload 形狀從 proto 的 google.api.http annotations 產生,不手寫 handler。

annotation 寫在 rpc 上,例如 sample resource:

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

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>'

沒帶 token 回 401。gateway 與 gRPC、MCP 走同一條攔截器鏈,錯誤 body 由統一錯誤模型輸出,不含內部原因。

gateway 對 request body 有 1 MiB 上限與 30 秒讀取逾時:超限回 413,讀取逾時回 408。

  • server.enable_cors: true 只是總開關;實際的 allowlist 是 server.cors_origins。沒列在 cors_origins 的 origin 拿不到任何 CORS headers——只開 enable_cors 而不設 origins,瀏覽器端照樣被擋。設 "*" 全開,或列明確 origin(也可用 GORTEXA_SERVER__CORS_ORIGINS 逗號分隔覆寫)。預檢 OPTIONS 直接短路。
  • server.openapi: true 時在 /openapi.json 提供 OpenAPI spec。spec 是 make gen 的建置產物,啟動時從工作目錄下的相對路徑 gen/openapiv2/gortexa.swagger.json 讀一次進記憶體。檔案不存在時 /openapi.json 回 404 openapi spec unavailable。容器 image 若需要這個端點,必須把檔案放在其 WORKDIR 下的同一相對路徑。

gateway 把 Authorization 與 X-Request-Id 轉送到固定的 metadata key,並拒絕任何會撞上受信 key(authorization、x-request-id、x-gortexa-peer-ip)的 Grpc-Metadata-* 標頭——client 無法在自己的 token、request id 或 rate-limit 身分上走私第二個值。另外,Authorization、X-Forwarded-For、X-Forwarded-Host 是 grpc-gateway 會逕自併進 outgoing metadata 而不自行檢查的三個標頭,因此 gateway 會過濾它們:非可列印 ASCII 的值直接丟棄而不轉送。若原樣放行,一個壞位元組會讓 loopback 在攔截器鏈執行之前就以 internal 失敗,呼叫端拿到的是沒有 request id 的 500,而不是鏈真正的判斷——匿名呼叫端等於可以任意拉高伺服器的 internal error 率。

回應 headers 走 allowlist:內部 headers 不會漏到外部,X-Request-Id 保留供關聯查詢。