Cloudflare
Pages Functions
Workers
API Routes
Serverless

Funzioni Pagine: quando usarle al posto delle Workers pure

La co-ubicazione di frontend e API nello stesso repository con distribuzioni di anteprima automatiche è il caso principale di Pages Functions, non una limitazione tecnica della piattaforma.

Funzioni Pagine: quando usarle al posto delle Workers pure

C'è un malinteso comune sulle Pages Functions: che siano una versione semplificata o limitata dei Workers, adatta a casi banali e insufficiente per una produzione seria. Non è vero. Le funzioni di Pages vengono eseguite sullo stesso runtime V8 dei Worker, accedono alle stesse associazioni, rispettano gli stessi limiti. La differenza tra le due forme di dispiegamento non è una questione di capacità, ma di contesto operativo.

Cosa sono le funzioni di Pages, tecnicamente

Le funzioni di Pages sono Worker distribuiti tramite convenzione di file system all'interno di un progetto Pages. Crei una directory /functions nella radice del repository e ogni TypeScript o file JavaScript lì diventa un percorso. Il file /functions/api/users/[id].ts risponde in /api/users/:id. Il file /functions/webhooks/stripe.ts risponde in /webhooks/stripe.

Il runtime che esegue questo codice è identico a quello di un Worker autonomo: isolati V8, avvio a freddo inferiore a 1 ms, 128 MB di memoria per invocazione (limite rigido), 30 secondi di CPU per richiesta sul piano a pagamento, 1.000 sottorichieste per invocazione. I collegamenti disponibili sono gli stessi: D1 per il database SQLite sul perimetro, KV per l'archiviazione di valori-chiave, R2 per oggetti, Oggetti durevoli per stato coerente, AI per inferenza, Collegamenti di servizio per chiamate dirette ad altri lavoratori.

La distinzione esiste nella distribuzione: una funzione Pages viene creata come parte di un progetto Pages che dispone anche di risorse statiche. Non è possibile distribuire una funzione Pages senza un progetto Pages. Questa non è una limitazione tecnica: è una scelta di prodotto che definisce quando ha senso utilizzare l'uno o l'altro.

Quando le Funzioni di Pages vincono

Il caso più forte per Pages Functions è la co-ubicazione: frontend e backend nello stesso repository, con lo stesso ciclo di distribuzione. Un progetto Next.js, Astro o SvelteKit con percorsi API è naturalmente co-localizzato: si modifica un componente e il percorso API che utilizza nello stesso commit, nella stessa richiesta pull, nella stessa distribuzione di anteprima.

Questa anteprima per filiale è il differenziatore operativo più concreto. Ogni push a qualsiasi ramo genera un URL di anteprima con il formato hash-nome-da-branch.seuproject.pages.dev, dove sono in esecuzione sia le risorse statiche che le funzioni. Ciò significa che il revisore PR può testare la funzionalità completa, interfaccia e API, senza distribuirla in un ambiente separato. I Pure Worker non hanno questo flusso in modo nativo.

Se il tuo routing API si associa naturalmente ai percorsi URL e non hai bisogno di una logica di routing complessa al di fuori della struttura della directory, le Funzioni di Pages eliminano la necessità di un Worker separato con i propri percorsi configurati in wrangler.toml.

La struttura della directory e il modello del middleware

Una struttura realistica del progetto Pages with Functions:

/functions
  _middleware.ts          ← executa antes de toda Function no diretório
  /api
    _middleware.ts        ← executa antes de toda Function em /api
    users/
      [id].ts             ← GET /api/users/:id, PUT /api/users/:id
      index.ts            ← GET /api/users, POST /api/users
    webhooks/
      stripe.ts           ← POST /api/webhooks/stripe

Il file _middleware.ts è un meccanismo di composizione che molte persone ignorano. Riceve la richiesta prima che la funzione specifica del percorso venga eseguita e può cortocircuitarla con la propria risposta o trasmetterla al gestore successivo tramite ctx.next(). Questo è per autenticazione, registrazione centralizzata e CORS senza ripetere la logica in ciascuna funzione:

// /functions/api/_middleware.ts export async function onRequest(ctx: EventContext<Env, any, any>) { const token = ctx.request.headers.get("Authorization"); if (!token || !isValidToken(token, ctx.env.JWT_SECRET)) { return new Response("Unauthorized", { status: 401 }); } const response = await ctx.next(); response.headers.set("X-Content-Type-Options", "nosniff"); return response; }

Il middleware nella radice /functions copre tutte le funzioni. Il middleware in /functions/api copre solo i percorsi API. Puoi impilarli: quello nella directory principale viene eseguito per primo.

Quando i Pure Workers sono la scelta giusta

Le funzioni di Pages non supportano i trigger cron. Se hai bisogno di un lavoro che venga eseguito alle 3 del mattino per elaborare la fatturazione, sincronizzare un feed esterno o pulire sessioni scadute, deve essere un lavoratore autonomo con [triggers] crons su wrangler.toml. Non esiste alcuna alternativa all'interno del modello Pages.

Anche i consumatori di coda, ovvero i lavoratori che elaborano i messaggi di Cloudflare Queues in modo asincrono, non esistono in Pages. Se la tua architettura utilizza le code per disaccoppiare l'elaborazione pesante dal percorso critico della richiesta, il consumatore deve essere un lavoratore separato.

Workers for Platforms, il meccanismo di invio degli script distribuiti dall'utente (nel caso di SaaS multi-tenant in cui ogni cliente ha il proprio codice), è esclusivo di Workers. Gli addetti alla posta elettronica, che ricevono ed elaborano le e-mail in arrivo, idem.

La regola pratica: se il trigger non è una richiesta HTTP, è un puro Worker. Le funzioni delle pagine sono esclusivamente HTTP.

Condivisione del codice tra funzioni e lavoratori di pagine separate

Un'architettura comune utilizza entrambi: il progetto Pages per il frontend e l'API principale in /functions, oltre a Worker separati per i lavori in background. Il problema è che potrebbe essere necessario condividere il codice aziendale: convalida dei dati, accesso al database D1, logica di autorizzazione.

La soluzione sono pacchetti npm interni (che utilizzano aree di lavoro npm/pnpm) o un lavoratore dedicato come "livello di servizio" a cui altri possono accedere tramite Service Binding. Il Service Binding consente ad una Funzione Pages di chiamare un Worker direttamente, sulla stessa rete Cloudflare interna, senza costi di rete e senza passare attraverso la rete internet pubblica:

// /functions/api/orders/index.ts export async function onRequestPost(ctx: EventContext<Env, any, any>) { // Chama o Worker de processamento via Service Binding const result = await ctx.env.ORDER_PROCESSOR.fetch( new Request("https://internal/process", { method: "POST", body: ctx.request.body, }) ); return result; }

Il ORDER_PROCESSOR qui è un Worker autonomo che ha accesso a code, cron e qualsiasi altra primitiva che le funzioni di Pages non supportano. Le funzioni delle pagine si trovano al livello HTTP; I lavoratori autonomi siedono in trigger asincroni. I due condividono i collegamenti D1 e KV che puntano alle stesse risorse.

I criteri decisionali

Se stai creando un progetto con un frontend, ovvero qualsiasi cosa che generi risorse statiche durante la creazione, inizia con Pages. Le funzioni aggiunte in /functions hanno esattamente la stessa potenza di un lavoratore autonomo per i casi HTTP. Ottieni l'anteprima della filiale e la pipeline di creazione integrata senza pagare costi operativi aggiuntivi.

Se stai creando un servizio senza frontend, con trigger non HTTP o che richiede ambienti denominati con associazioni diverse per gestione temporanea e produzione, Workers è il percorso più diretto. La configurazione esplicita in wrangler.toml è più controllabile e il modello di distribuzione è più flessibile per i servizi backend puri.

I due non si escludono a vicenda. I progetti più seri finiscono con entrambi: pagine per ciò che è HTTP e co-localizzate con il frontend, lavoratori per ciò che è asincrono o pianificato.

Leggi anche