Skip to Content
操作流程呼叫 API

呼叫 API

兩條通道到達同一份已部署程式碼。兩邊的方法:GET、POST、PUT、PATCH、DELETE — 沒有 HEAD、沒有 OPTIONS(公開通道自己回應 OPTIONS 做 CORS preflight)。

通道 1 — 經驗證的閘道(任何存取模式)

<METHOD> {BASE}/private/module/edge-workers/worker/invoke/<declared-path>?<query> Authorization: Bearer <jwt> # any department member

管線:raw-path 圍欄(%2f/%5c 在解碼前拒絕)→ Worker 必須 active 且有已部署的 current 修訂版 → 重新計算 release generation → 路徑對三個上限驗證 → 解析服務位置 → 讀 body(≤1 MiB)→ 鑄造 30 秒 EdDSA 簽章斷言(攜帶每次呼叫的 limits)→ dispatcher → 你的 handler — 回應原樣串流回來(含狀態碼),上限 5 MiB。閘道送往 dispatcher 時一律使用自己的 User-Agent: teamsync-backend-edge-gateway — dispatcher 的 workers.dev 主機上的 Cloudflare 瀏覽器完整性檢查,會在 dispatcher 執行前以不透明的 403 error code: 1010 回應某些函式庫 agent(例如 Python-urllib),閘道呼叫者不再遇到這個問題;你的 handler 會在 x-client-user-agent 收到呼叫者的 agent。呼叫者必須是仍有效的真人成員:部門服務帳號的 JWT 會得到 403 Service accounts cannot invoke Edge Workers。這條通道永遠不套用存取政策或逐操作准入。其他 TeamSync 功能(Custom Tables 的觸發與排程、QA 資料來源)也會以設定它們的使用者身分,經這條簽章通道呼叫你的操作。

失敗狀態 + detail
路徑不合法/帶編碼分隔符,或 /_teamsync/control404 Worker operation not found
沒有 Worker/非 active/沒有已部署版本404 Department Worker not found
路徑超過上限414 Worker request path exceeds gateway limits
Query > 1024 位元組/非 ASCII query414 Worker request query exceeds gateway limits/400 Worker request query is invalid
Body > 1 MiB413 Worker request body exceeds 1 MiB
Release 列格式錯誤503 Deployed department Worker release is unavailable
Worker 已記錄的服務位置不一致503 Department Worker serving target is unavailable
dispatcher/傳輸失敗,或後端無法簽章(簽章或 EDGE_WORKERS_LIMIT_* 設定不合法)503 Department Worker gateway is unavailable
你 handler 的回答,或 dispatcher 的回答(例如在 Worker 的位置變動時,有幾秒鐘回 409 serving_target_mismatch)原樣穿透(僅去掉 hop-by-hop 與 set-cookie)

併發部署不會讓請求腦裂:script 名稱 + release generation 在讀 body 之前就快照,runtime 在選路之前以 503 release_generation_mismatch 拒絕 generation 不符。Worker paused(部署結算中或 uncertain;部署最多會等新的 release 回應 10 分鐘)→ 新准入 404;已准入的請求可以在對應的舊 bundle 上跑完。

通道 2 — 公開 dispatcher(依模式)

Base URL = GET /worker/openapi.json 的 servers[0].url(存取設定與 Worker 全域政策不同的操作,可能在該文件中帶有自己的 servers 與 security):

https://<dispatcher-host>/public/<script_name>/<declared-path>

在地端套件上,同一路徑位於套件的位址之下:https://<kit-host>/edge/public/<script_name>/<declared-path>。

由存取模式准入:public — 無條件;api_key — header X-TeamSync-Worker-Key: tsw_…(錯誤/缺少 → 401 access_denied);ip_allowlist — 用戶端 IP 落在設定的 CIDR(→ 403);api_key_and_ip — 兩者皆要(拒絕 → 403);teamsync_internal — 整條通道關閉(403)。以 builder policy v2.8 以上建置的修訂版,runtime 會在選路之後依比對到的操作准入:每個操作依其有效政策檢查 — 若其操作設定覆寫了模式、IP 允許清單與金鑰就用自己的,否則用 Worker 全域政策。沒有比對到任何操作的路徑或錯誤的 method,仍會先依 Worker 全域政策准入,再得到 404/405。當正在服務的 release generation 還沒有操作設定(部署進行中)時,所有公開請求都會得到 403 operation_settings_pending,直到後端寫入設定為止。

dispatcher 層錯誤(外層 {code, message, requestId}):405 method_not_allowed、414 request_query_too_large(>1024 B)、400 request_query_invalid、413 request_body_invalid(>1 MiB 或 GET 帶 body)、404 worker_not_found、429 worker_limit_exceeded(CPU 50 ms/500 子請求 — 這條通道用 dispatcher 自己的變數;地端則是牆鐘時間預算)、502 worker_execution_failed、503 dispatcher_unavailable(dispatcher 設定錯誤)。404 worker_not_found 表示沒有任何綁定的位置持有這個 script(或 script 被釘選的位置沒有它),或是已退役 Worker 的墓碑回答了請求;從 Worker 逸出的例外即使訊息寫著 Worker not found,也是 502。CORS:access-control-allow-origin: *、公開 header X-TeamSync-Request-Id、永遠沒有帶憑證的 CORS。公開流量不綁 release — 永遠打到當下上線的修訂版。

runtime 層的回答(兩條通道相同)

生成的 router 依序檢查:503 worker_unavailable(儲存 stub 連不上);401 dispatch_context_invalid/503 release_generation_mismatch(dispatch context);503 worker_unavailable(無法載入 Worker 儲存的狀態);503 migration_fenced(平台把 Worker 搬到另一個位置期間,Worker 被凍結,見搬移 Worker;兩條通道上的每個請求,在選路之前);403 worker_retired(Worker 正在退役;兩條通道上的每個請求,在選路之前);選路 — 公開通道上,沒比對到的路徑會先遇到 403 operation_settings_pending 或 Worker 全域的 401/403 access_denied — 接著是 404 operation_not_found 或 405 method_not_allowed(帶 Allow);500 worker_contract_error(缺 export);公開通道上的 403 operation_settings_pending,然後是該操作的 401/403 access_denied;最後是你的 handler:500 worker_contract_error(回傳非 Response)、500 worker_execution_failed(handler 丟例外)。handler 丟出的錯誤永不外洩堆疊 — 結構化日誌以 request id 為鍵記錄 operationId 與錯誤類型。

關聯

每個回應都帶 x-teamsync-request-id — 一個 UUID 貫穿 dispatcher 日誌 → runtime 日誌 → 客戶端,兩條通道皆然。回報平台問題時請附上它。在雲端,dispatcher 還會在每個由 Worker 產生的回應上設定 x-teamsync-serving-namespace 與 x-teamsync-routing-epoch(覆寫你的程式碼設定的同名 header);它們是平台診斷資訊 — 不要解析它們,也不要據以撰寫邏輯。

你的 handler 收到什麼

{request, params, query, operationId, storage, config, secrets, teamsync},凍結;所有 cf-*、x-forwarded-*、x-teamsync-* header 已剝除;authorization、cookie、x-api-key 與 hop-by-hop header 永不轉發。secrets.get(name) 讀取一個 Worker 機密(未設定時為 undefined;builder policy v2.6 以上);teamsync 提供該操作所綁定服務帳號的 apiBase 與 authHeaders()(builder policy v2.9 以上)。閘道通道上,request.headers 帶的是 user-agent: teamsync-backend-edge-gateway,呼叫者原本的 agent 在 x-client-user-agent(≤256 字元,呼叫者沒送時不存在;後端會丟棄呼叫者自帶的同名 header)。公開通道上兩者都是公開呼叫者送來的原值 — x-client-user-agent 只有在閘道通道上才可信。你讀不到呼叫者 IP(准入政策除外)、也設不了 cookie。在雲端,對任何目的地的 fetch() 都允許 — 不受限制,路徑上沒有 Outbound Worker — 但每次呼叫預設限 500 個子請求與 50 ms CPU(超過回 429 worker_limit_exceeded;限制);在地端,對外連線排除 loopback、link-local 與 edge 控制子網路,界限則是牆鐘時間預算與每個行程共用的子請求額度(地端)。在兩種 runtime 上,handler 程式碼都無法使用原始 TCP connect():builder 會以 source_import_forbidden 拒絕 cloudflare:sockets 的匯入。

Last updated on