# HTTP/JSON

Source: https://gortexa.sheng.page/transports/http-json/

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

## 路由對應

annotation 寫在 rpc 上，例如 sample resource：

```protobuf
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}` |

## 呼叫與 auth

```bash
curl localhost:8080/v1/resources/x \
  -H 'Authorization: Bearer <token>'
```

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

## Request body 上限

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

## CORS 與 OpenAPI

- `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` 下的同一相對路徑。

## 請求 headers

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

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

## 延伸閱讀

- [httpcompat 元件](https://gortexa.sheng.page/components/http-mcp/)：建立 gateway mux 的 API
- [核心概念](https://gortexa.sheng.page/concepts/)：錯誤模型如何決定 HTTP status
- [框架比較](https://gortexa.sheng.page/comparison/)：和只用 grpc-gateway 的差別
