I weekenden havde jeg brug for et offentligt endpoint til at modtage formularindsendelser fra en landingsside. Intet fancy — modtag en JSON-POST, validér et par felter, returnér et fornuftigt svar. Det hele ville håndtere måske 50 requests om ugen. Jeg gad ikke lægge et kreditkort på en $20/måned-server, lære et nyt infra-værktøj eller sidde igennem en CI-pipeline hver gang jeg ændrede tre linjer. Ti minutter efter jeg startede, var API'et live i 300+ byer og kostede mig nul dollars. Her er gennemgangen.

Cloudflare Workers har et gratisniveau, der faktisk er gavmildt: 100.000 requests om dagen, intet kreditkort krævet for at melde sig til, og din kode kører ved edge i stedet for i én region. For de små API'er, som de fleste sideprojekter har brug for — webhook-modtagere, formularhåndterere, link-forkortere, JSON-proxyer — kan du shippe og glemme. Denne guide tager dig fra "ingen Cloudflare-konto" til "live URL der svarer på curl" på cirka ti minutter. Vi bygger et rigtigt endpoint: en JSON-validator der modtager en POST, tjekker payloaden og ekkoer et rent svar tilbage.

Hvad du får gratis (og hvad du ikke får)

Cloudflare Workers gratisplan giver dig 100.000 requests om dagen og 10 millisekunders CPU-tid pr. request. Det lyder stramt, indtil du indser at de fleste JSON-endpoints — parse body, gør en smule arbejde, returnér et svar — bliver færdige langt under 1 ms. 10 ms-loftet er CPU-tid, ikke vægur-tid, så en upstream-fetch der tager 800 ms tæller stadig som omkring 1 ms CPU, fordi din kode mest venter på I/O.

Hvad du ikke får på gratisplanen: persistent lagring med højt throughput (Workers KV har sin egen gratis-kvote — gavmild i de fleste tilfælde, men separat fra request-tællingen), store svar-payloads, eller planlagte cron-triggers oftere end én gang i minuttet. For en typisk "modtag JSON, gør en ting, returnér JSON"-tjeneste der ikke har brug for en database, vil du ikke ramme en mur.

Intet kreditkort ved tilmelding. Når du opretter kontoen, beder Cloudflare om en mail og en adgangskode — det er det. Dashboardet beder dig dog om at tilføje fakturering senere for betalte produkter, men gratisniveauet for Workers behøver intet og vil ikke overraske dig med en opkrævning.

Installér Node.js og Wrangler

Wrangler er Cloudflares CLI til Workers. Installér den via npm — du har brug for Node.js 18 eller nyere. Har du allerede Node, er det en one-liner:

bash
npm install -g wrangler

# Verify
wrangler --version
# Should print 3.x or higher

Log nu ind. Det åbner en browser til OAuth, opretter Cloudflare-kontoen hvis du ikke har en, og gemmer credentials lokalt:

bash
wrangler login

# Opens https://dash.cloudflare.com/oauth/authorize ...
# After you approve: "Successfully logged in."

Scaffold projektet

Én kommando og du har et projekt-skelet med fornuftige defaults — en eksempel- fetch-handler, en wrangler.toml-config, og den lokale dev-server allerede sat op:

bash
npm create cloudflare@latest free-json-api

# When prompted, pick:
#   "Hello World" Worker
#   JavaScript (or TypeScript — your call)
#   No deploy yet (we'll do that ourselves)

cd free-json-api

Generatoren smider alt du har brug for i én mappe. Åbn src/index.js — det er filen din Worker kører. Vi udskifter dens indhold med noget mere brugbart end standard-Hello World.

Skriv JSON-API'et

Her er en komplet Worker, der modtager en JSON-POST, validerer to påkrævede felter og returnerer et rent svar. Den håndterer de almindelige fejlsituationer — forkert metode, malformet JSON, manglende felter — i stedet for at crashe ud i en generisk 500:

js
export default {
  async fetch(request) {
    if (request.method !== 'POST') {
      return Response.json(
        { error: 'POST only' },
        { status: 405 },
      );
    }

    let body;
    try {
      body = await request.json();
    } catch {
      return Response.json(
        { error: 'Body must be valid JSON' },
        { status: 400 },
      );
    }

    const { email, message } = body;
    if (typeof email !== 'string' || typeof message !== 'string') {
      return Response.json(
        { error: 'email and message are required (strings)' },
        { status: 422 },
      );
    }

    return Response.json({
      ok: true,
      receivedAt: new Date().toISOString(),
      echo: { email, message },
    });
  },
};

To ting værd at fremhæve. Response.json() serialiserer objektet og sætter Content-Type: application/json for dig, så du ikke skal huske headeren. Og at pakke request.json() ind i en try/catch er den enkeltvigtigste vane når man bygger Workers — uden den returnerer en malformet payload en uigennemskuelig 500 fra Cloudflares runtime i stedet for en brugbar 400 fra din kode.

Test det lokalt

Wrangler kommer med en lokal dev-server, der kører samme V8-isolat som Cloudflare bruger i produktion. Start den med:

bash
npm run dev

# ⛅️ wrangler 3.x
# [wrangler:inf] Ready on http://localhost:8787

I en anden terminal, ram den med curl. Prøv happy path først, derefter en bevidst ødelagt payload — du burde se rene JSON-fejl i stedet for stack traces:

bash
# Happy path
curl -X POST http://localhost:8787 \
  -H "Content-Type: application/json" \
  -d '{"email":"[email protected]","message":"hello"}'

# {"ok":true,"receivedAt":"2025-10-15T...","echo":{...}}

# Broken JSON (note the missing closing brace)
curl -X POST http://localhost:8787 \
  -H "Content-Type: application/json" \
  -d '{"email": "ava"'

# {"error":"Body must be valid JSON"}

# Missing required field
curl -X POST http://localhost:8787 \
  -H "Content-Type: application/json" \
  -d '{"email":"[email protected]"}'

# {"error":"email and message are required (strings)"}
Tip: hvis et svar ser skævt ud i din terminal, indsæt det i JSON Formatter for at pretty-printe og inspicere. Jeg gør det tyve gange om dagen, når jeg arbejder med ukendte API'er.

Deploy til verden — én kommando

Når lokalt virker, skub det globalt:

bash
npx wrangler deploy

# Total Upload: 1.18 KiB / gzip: 0.55 KiB
# Uploaded free-json-api (1.34 sec)
# Published free-json-api (4.21 sec)
#   https://free-json-api.<your-subdomain>.workers.dev
# Current Deployment ID: ...

Den URL er nu live på hvert Cloudflare-datacenter. En request fra Berlin rammer Frankfurt, en fra Tokyo rammer Tokyo, en fra São Paulo rammer São Paulo — samme kode, ingen ekstra konfig. Bundlen var 1,2 KiB. Test live-URL'en med de samme curl-kommandoer du brugte lokalt — udskift bare localhost:8787 med workers.dev-værtsnavnet Wrangler udskrev.

Når du vokser fra gratisniveauet

Det varer længe. 100k requests/dag er groft sagt 1,15 requests pr. sekund i gennemsnit over 24 timer — komfortabelt mere end de fleste sideprojekter, interne værktøjer eller tidlige produkter laver. Det første der typisk skubber dig af gratisniveauet er ikke request-antallet, men lagring: hvis du begynder at skrive meget til KV, R2 eller D1, har de deres egne kvoter. Den betalte plan starter ved $5/måned og giver dig 10 millioner requests, mere CPU pr. request, og et kreditkort- sikkerhedsnet for spikes. De fleste projekter får aldrig brug for den.

Hvad så nu

Det du har shippet er den absolutte minimums-brugbare Worker. Rigtige produktions-endpoints har brug for et par vaner mere — CORS for browser-kaldere, secrets-håndtering for API-nøgler, edge-caching for langsomme upstreams, og en strategi for at proxy'e upstream-tjenester. Jeg dækkede dem i Cloudflare Workers og JSON — en praktisk guide, der tager fat hvor denne artikel slutter.

Et par værktøjer jeg holder åbne, mens jeg bygger Workers der arbejder med JSON: JSON Formatter til at pretty-printe svar, JSON Validator til at finde ud af præcis hvorfor en payload blev afvist, og JSON Path til at planlægge felt-pluk-logik før jeg skriver den. Selve JSON-formatet er specificeret i RFC 8259 — værd at skimme, når du begynder at håndtere mærkelige inputs fra rigtige brugere.

For dybere Worker-mønstre — KV-lagring, Durable Objects, planlagte triggers, AI-inference- bindingerne — er Cloudflares Workers examples-galleri den bedste ressource jeg har fundet. Det er en copy-pasteable liste af opskrifter til de næste skridt.

Afrunding

Cloudflare Workers er det sjældne gratisniveau, der faktisk er brugbart til rigtige side- projekter. Intet kreditkort for at starte, 100k requests om dagen, og en deploy-historie der passer i en enkelt kommando. Mønsteret i denne artikel — modtag JSON, validér, returnér JSON — dækker en overraskende stor del af, hvad de fleste API'er gør. Har du holdt dig fra at shippe et lille API fordi infraen føltes som et besvær, er det her stien jeg ville ønske jeg havde taget for tre år siden.