{
  "id": "build-a-cloudflare-worker-api-proxy",
  "type": "prompts",
  "category": "prompts",
  "locale": "de",
  "url": "/de/prompts/build-a-cloudflare-worker-api-proxy",
  "title": "Prompt zum Erstellen eines Cloudflare Worker API-Proxys",
  "description": "Kopieren-Einfügen AI-Prompt zum Erstellen eines Cloudflare Workers, der externe API-Aufrufe proxyt und ratenbegrenzt, Auth-Header hinzufügt und Antworten zwischenspeichert.",
  "tools": [
    "Cursor",
    "Claude Code",
    "Codex",
    "Windsurf"
  ],
  "stack": [
    "Cloudflare",
    "TypeScript"
  ],
  "tags": [
    "cloudflare",
    "typescript",
    "security",
    "deploy"
  ],
  "difficulty": "medium",
  "updated": "2026-06-08",
  "markdown": "Verwenden Sie diesen Prompt, um einen Cloudflare Worker zu erstellen, der vor einer externen API sitzt,\nAuth-Header injiziert, das Raten-Limit pro IP mit Workers KV durchsetzt und Antworten zwischenspeichert –\nsodass Clients nie Ihren Upstream-API-Schlüssel sehen.\n\n## Haupt-Prompt\n\n```txt title=\"Main Prompt\"\nYou are building a Cloudflare Worker using TypeScript and the Workers runtime (not Node.js).\nThe Worker will proxy requests to an upstream API (e.g., OpenAI at https://api.openai.com).\n\nTask: create a production-ready API proxy Worker.\n\nRequirements:\n- Use `wrangler` v3 for local dev. Scaffold with `bun create cloudflare@latest` and choose\n  \"Hello World\" Worker with TypeScript.\n- Upstream URL: read from a Wrangler secret `UPSTREAM_URL` (string).\n- Auth: inject `Authorization: Bearer ${env.UPSTREAM_API_KEY}` on every proxied request,\n  where `UPSTREAM_API_KEY` is a Wrangler secret. Never expose this header to the client.\n- CORS: allow only origins in `env.ALLOWED_ORIGINS` (comma-separated string secret).\n  Return a `403` for disallowed origins. Handle preflight OPTIONS requests.\n- Rate limiting: use Workers KV binding `RATE_LIMIT_KV`.\n  - Key: `rl:${ip}` where ip is `request.headers.get('CF-Connecting-IP')`.\n  - Value: request count for the current UTC minute (TTL = 60 s).\n  - Limit: 60 requests/minute per IP. Return `429` with `Retry-After: 60` if exceeded.\n- Caching: for GET requests, check `caches.default` before proxying upstream. Cache\n  successful responses with `Cache-Control: public, max-age=300`.\n- Strip the following headers from the upstream response before returning to the client:\n  `x-powered-by`, `server`, `cf-ray`.\n- Wrangler config: declare the KV namespace binding and all secrets in `wrangler.toml`.\n- Do NOT use Node.js APIs (`fs`, `path`, `Buffer`) — Workers runtime only.\n\nStop and list all planned files before writing code.\n```\n\n## Implementierungshinweise\n\n- Cloudflare Workers empfangen ein `Request` und geben ein `Response` zurück – vermeiden Sie `express`-artige Muster.\n- `caches.default` ist der Cloudflare-Edge-Cache; er funktioniert nur in der Produktion. Verwenden Sie `MINIFLARE_CACHE`\n  für lokale Entwicklungstests oder mocken Sie den Cache.\n- `CF-Connecting-IP` wird von Cloudflare injiziert – es ist vom öffentlichen Internet aus nicht spoofbar, aber\n  testen Sie lokal mit einer hartcodierten Fallback-IP.\n- Wrangler-Secrets werden mit `wrangler secret put UPSTREAM_API_KEY` gesetzt – speichern Sie sie niemals in\n  `wrangler.toml` oder in committed `.env`-Dateien.\n\n## Erwartete Dateiänderungen\n\n```txt\nwrangler.toml                  (new)\nsrc/index.ts                   (new — Worker entrypoint)\nsrc/cors.ts                    (new — CORS helper)\nsrc/rate-limit.ts              (new — KV rate limiter)\npackage.json                   (new)\ntsconfig.json                  (new)\n.dev.vars                      (new — local dev secrets, gitignored)\n.gitignore                     (edited — add .dev.vars)\n```\n\n## Akzeptanzkriterien\n\n- `wrangler dev` startet ohne Fehler und leitet einen `GET /` an die Upstream-URL weiter.\n- Eine IP, die 61 Anfragen in einer Minute sendet, erhält beim 61. Request einen `429`.\n- Eine Anfrage von einer nicht erlaubten Domain erhält einen `403`.\n- Der `Authorization`-Header erscheint weder in der Antwort noch in einem client-sichtbaren Header.\n- `wrangler deploy` ist erfolgreich und der Worker ist live auf `workers.dev`.\n\n## Testbefehle\n\n```bash\nwrangler dev &\n# test normal proxy\ncurl http://localhost:8787/ -H \"Origin: https://myapp.com\"\n# test CORS rejection\ncurl http://localhost:8787/ -H \"Origin: https://evil.com\"\n# test rate limit (requires 61 rapid requests)\nfor i in $(seq 1 62); do curl -s -o /dev/null -w \"%{http_code}\\n\" http://localhost:8787/; done\n```\n\n## Häufige KI-Fehler\n\n- Verwendung von `process.env` anstelle des `env`-Parameters, der an den Worker-`fetch`-Handler übergeben wird.\n- Vergessen, `OPTIONS`-Preflight-Anfragen zu behandeln, was CORS für POST/PUT-Aufrufe unterbricht.\n- Speichern von `UPSTREAM_API_KEY` in `wrangler.toml` als einfache Variable anstelle eines Secrets.\n- Verwendung von `node:buffer` oder anderen Node.js-Builtins, die in der Workers-Laufzeitumgebung nicht verfügbar sind.\n\n## Fix-Prompt\n\n```txt title=\"Fix Prompt\"\nThe Worker fails with a runtime error or leaks the API key. Fix in order:\n1. Replace `process.env.X` with `env.X` everywhere — Workers use the `env` handler parameter.\n2. Add an OPTIONS handler before the proxy logic that returns the CORS headers with a 204 status.\n3. Move `UPSTREAM_API_KEY` from `wrangler.toml` [vars] to a secret: `wrangler secret put UPSTREAM_API_KEY`.\nShow only the corrected diff.\n```"
}