Lo scorso fine settimana mi serviva un endpoint pubblico per ricevere i submit di un form da una landing page. Niente di speciale — accettare un POST JSON, validare un paio di campi, restituire una risposta sensata. L'intera cosa avrebbe gestito forse 50 richieste a settimana. Non avevo voglia di mettere una carta di credito su un server da 20$/mese, imparare un nuovo strumento di infra, o aspettare una pipeline CI ogni volta che cambiavo tre righe. Dieci minuti dopo aver iniziato, l'API era live in oltre 300 città e mi costava zero dollari. Questo è il walkthrough.
Cloudflare Workers
ha un piano gratuito davvero generoso: 100.000 richieste al giorno, niente carta di credito richiesta per
iscriversi, e il tuo codice gira sull'edge invece che in una sola region. Per le piccole API di cui hanno bisogno la maggior parte
dei side project — receiver di webhook, handler di form, accorciatori di link, proxy JSON — puoi
deployare e dimenticartene. Questa guida ti porta da "nessun account Cloudflare" a "URL live che risponde a
curl" in circa dieci minuti. Costruiremo un endpoint vero: un validator JSON che
accetta un POST, controlla il payload e restituisce in eco una risposta pulita.
Cosa ottieni gratis (e cosa no)
Il piano gratuito di Cloudflare Workers ti dà 100.000 richieste al giorno e 10 millisecondi di tempo CPU per richiesta. Sembra stretto finché non ti accorgi che la maggior parte degli endpoint JSON — parsifica il body, fai un pochino di lavoro, restituisci una risposta — finiscono ben sotto 1ms. Il tetto di 10ms è tempo CPU, non tempo wall-clock, quindi una fetch upstream che impiega 800ms conta comunque come circa 1ms di CPU perché il tuo codice è perlopiù in attesa di I/O.
Quello che non ottieni nel piano gratuito: storage persistente ad alta velocità (Workers KV ha la sua quota gratuita — generosa nella maggior parte dei casi, ma separata dal conteggio richieste), payload di risposta di grandi dimensioni, o trigger cron pianificati più frequenti di una volta al minuto. Per un tipico servizio "ricevi JSON, fai una cosa, restituisci JSON" che non ha bisogno di un database, non sbatterai contro un muro.
Installa Node.js e Wrangler
Wrangler è la CLI di Cloudflare per Workers. Installalo via npm — ti servirà Node.js 18 o più recente. Se hai già Node, è una one-liner:
npm install -g wrangler
# Verify
wrangler --version
# Should print 3.x or higherOra fai login. Questo apre un browser per OAuth, crea l'account Cloudflare se non ce l'hai e memorizza le credenziali localmente:
wrangler login
# Opens https://dash.cloudflare.com/oauth/authorize ...
# After you approve: "Successfully logged in."Scaffold del progetto
Un comando e hai uno scheletro di progetto con default sensati — un handler
fetch di esempio, una config wrangler.toml e il dev server locale
già cablato:
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-apiIl generator ti mette tutto quello che ti serve in una sola cartella. Apri src/index.js —
è il file che il tuo Worker esegue. Ne sostituiremo il contenuto con qualcosa di più utile dell'
Hello World di default.
Scrivi la JSON API
Ecco un Worker completo che accetta un POST JSON, valida due campi obbligatori, e restituisce una risposta pulita. Gestisce le modalità di errore comuni — metodo sbagliato, JSON malformato, campi mancanti — invece di crashare in un generico 500:
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 },
});
},
};Due cose che vale la pena sottolineare.
Response.json()
serializza l'oggetto e imposta Content-Type: application/json per te, così
non devi ricordarti l'header. E avvolgere request.json() in un try/catch è
la singola abitudine più importante quando costruisci Worker — senza, un payload malformato restituisce
un opaco 500 dal runtime di Cloudflare invece di un utile 400 dal tuo codice.
Testalo localmente
Wrangler è dotato di un dev server locale che esegue lo stesso isolato V8 che Cloudflare usa in produzione. Avvialo con:
npm run dev
# ⛅️ wrangler 3.x
# [wrangler:inf] Ready on http://localhost:8787In un altro terminale, picchialo con curl. Prova prima il percorso felice, poi un
payload deliberatamente rotto — dovresti vedere errori JSON puliti invece di stack trace:
# 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)"}Deploy al mondo intero — un comando
Quando il locale funziona, mandalo globale:
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: ...Quell'URL è ora live su ogni data center Cloudflare. Una richiesta da Berlino colpisce
Francoforte, una da Tokyo colpisce Tokyo, una da San Paolo colpisce San Paolo — stesso codice, nessuna config
extra. Il bundle era di 1,2 KiB. Testa l'URL live con gli stessi comandi curl che hai
usato in locale — basta scambiare localhost:8787 con l'hostname workers.dev
che Wrangler ha stampato.
Quando supererai il piano gratuito
Per molto tempo, non lo farai. 100k richieste al giorno sono circa 1,15 richieste al secondo in media nelle 24 ore — ben oltre quello che fanno la maggior parte dei side project, dei tool interni o dei prodotti early-stage. La prima cosa che di solito ti spinge fuori dal piano gratuito non è il conteggio richieste ma lo storage: se inizi a scrivere molto su KV, R2 o D1, hanno le loro quote. Il piano a pagamento parte da 5$/mese e ti dà 10 milioni di richieste, più CPU per richiesta e una rete di sicurezza da carta di credito per i picchi. La maggior parte dei progetti non ne ha mai bisogno.
Cosa viene dopo
Quello che hai spedito è il Worker utile minimo. Endpoint di produzione veri hanno bisogno di qualche abitudine in più — CORS per chiamanti browser, gestione dei secret per le API key, caching sull'edge per upstream lenti, e una strategia per il proxying di servizi upstream. Ne ho parlato in Cloudflare Workers e JSON — una guida pratica, che riprende dove finisce questo articolo.
Alcuni strumenti che tengo aperti mentre costruisco Worker che lavorano con JSON: JSON Formatter per fare pretty-print delle risposte, JSON Validator per capire esattamente perché un payload è stato rifiutato, e JSON Path per pianificare la logica di estrazione campi prima di scriverla. Il formato JSON di per sé è specificato nell' RFC 8259 — vale una scorsa veloce una volta che inizi a gestire input strani da utenti reali.
Per pattern Worker più approfonditi — storage KV, Durable Objects, trigger pianificati, i binding di inferenza AI — la galleria di esempi Workers di Cloudflare è la migliore risorsa che ho trovato. È una lista copia-e-incolla di ricette per i prossimi passi.
Tiriamo le somme
Cloudflare Workers è quel raro piano gratuito che è davvero usabile per side project veri. Niente carta di credito per iniziare, 100k richieste al giorno e una storia di deploy che sta in un singolo comando. Il pattern in questo articolo — accetta JSON, valida, restituisci JSON — copre una quantità sorprendente di ciò che fanno la maggior parte delle API. Se hai rimandato la spedizione di una piccola API perché l'infra ti sembrava una rottura, questo è il percorso che avrei voluto prendere tre anni fa.