Upstream proxy & mock service
An app can sit in front of an existing API (legacy ERP, partner service) and replace it one endpoint at a time, mock what is not ready, or simulate failures — while every request is logged.
import { env } from "cloudflare:workers";
// app/upstream.ts — one object or a list; prefix is the app path (with /api)
export default [
{ prefix: "/api/erp", origin: "https://erp.congty.vn/api" }, // auth: "forward" (default)
{ prefix: "/api/pay", origin: "https://pay.partner.vn", auth: "service",
headers: { authorization: `Bearer ${env.PAY_TOKEN}` } }, // token from Secrets (env_set)
];- Order: a Manh handler that matches (method + path) always wins; a request under a prefix with no handler is forwarded to
origin + <rest of the path>(method, query, body, headers exceptcookie/host/x-ft-*; redirects passed through,set-cookiedropped). Outside every prefix → normal 404. Longest prefix first. - auth:
"forward"passes the user’sAuthorizationheader to the real system (the app has no login of its own)."service"drops it and sendsheadersinstead (a service token from Secrets); the app then does its own DIY login. - Change an answer — in a handler:
const res = await upstream(c)(same request) orupstream(c, { path: "/api/erp/orders/" + id, method: "GET" }), then return what you want. - Mock —
return mock(c, data, { status?, delay? })answers without calling the real system; logged as sourcemock. Switch mocks without a deploy with a$mockstore value (D40) the owner edits in Dữ liệu → JSON:import { mock, upstream } from "app/std/upstream"; export default async function handler(c) { const mode = $mock?.["GET /api/erp/orders"] ?? "real"; // "real" | "mock" | "error500" | "slow3s" if (mode === "error500") return mock(c, { message: "ERP lỗi" }, { status: 500 }); if (mode === "slow3s") return mock(c, SAMPLE_ORDERS, { delay: 3000 }); if (mode === "mock") return mock(c, SAMPLE_ORDERS); return upstream(c); } - Traffic log: every
/apirequest of a Durable Object app is written toft_traffic(method, path, status, sourcehandler | upstream | mock | error, timings, masked headers, bodies ≤ 8 KB, text/JSON only;authorization,cookie,x-api-keyand fields named likepassword/token/secret/otpare masked). Kept 7 days / 20,000 rows.log: { bodies: false }on any upstream entry stops recording bodies. Owner: Vận hành → Lưu lượng; agent:logs({ type: "traffic" })— write mocks and tests from recorded real responses. - Rules (check):
originmust be a string literalhttps://public domain — no IP,localhost,*.local/*.internal, manh.run orworkers.devhosts (upstream.origin-invalid, also enforced at runtime);app/upstream.tswithout an origin →upstream.origin-missing. API only — proxying whole websites (HTML) is not supported. Never hard-code the upstream token (code.hardcoded-secret). - The live preview does not call upstreams; test against the deployed app.
Last updated on