Cloudflare
Pages Functions
Workers
API Routes
Serverless

Fonctions Pages : quand utiliser à la place des Workers purs

La colocalisation du frontend et de l'API dans le même référentiel avec des déploiements de prévisualisation automatiques est le cas principal de Pages Functions, et non une limitation technique de la plate-forme.

Fonctions Pages : quand utiliser à la place des Workers purs

Il existe une idée fausse courante à propos des fonctions Pages : il s'agit d'une version simplifiée ou limitée de Workers, adaptée aux cas triviaux et insuffisante pour une production sérieuse. Ce n'est pas vrai. Les fonctions Pages s'exécutent sur le même runtime V8 que les Workers, accèdent aux mêmes liaisons, respectent les mêmes limites. La différence entre les deux formes de déploiement ne réside pas dans la capacité, mais plutôt dans le contexte opérationnel.

Quelles sont les fonctions des pages, techniquement

Les fonctions Pages sont des Workers déployés via la convention du système de fichiers dans un projet Pages. Vous créez un répertoire /functions à la racine du référentiel, et chaque fichier TypeScript ou JavaScript y devient une route. Le fichier /functions/api/users/[id].ts répond en /api/users/:id. Le fichier /functions/webhooks/stripe.ts répond en /webhooks/stripe.

Le runtime qui exécute ce code est identique à celui d'un Worker autonome : V8 isole, démarrage à froid en dessous de 1 ms, 128 Mo de mémoire par invocation (limite stricte), 30 secondes de CPU par requête sur le forfait payant, 1 000 sous-requêtes par invocation. Les liaisons disponibles sont les mêmes : D1 pour la base de données SQLite en périphérie, KV pour le stockage clé-valeur, R2 pour les objets, Objets durables pour un état cohérent, AI pour l'inférence, Liaisons de service pour les appels directs à d'autres Workers.

La distinction existe dans le déploiement : une fonction Pages est créée dans le cadre d'un projet Pages qui possède également des actifs statiques. Il n'est pas possible de déployer une fonction Pages sans projet Pages. Il ne s'agit pas d'une limitation technique, mais d'un choix de produit qui définit quand il est judicieux d'utiliser l'un ou l'autre.

Quand les fonctions Pages gagnent

L’argument le plus solide pour Pages Functions est la colocalisation : frontend et backend dans le même référentiel, avec le même cycle de déploiement. Un projet Next.js, Astro ou SvelteKit avec des routes API est naturellement colocalisé : vous modifiez un composant et la route API qu'il consomme dans le même commit, la même demande d'extraction, le même déploiement d'aperçu.

Cette prévisualisation par branche constitue le différenciateur opérationnel le plus concret. Chaque poussée vers n'importe quelle branche génère une URL d'aperçu au format hash-nome-da-branch.seuproject.pages.dev, où les ressources statiques et les fonctions sont exécutées. Cela signifie que le réviseur des relations publiques peut tester la fonctionnalité complète (interface et API) sans la déployer dans un environnement distinct. Les Pure Workers n’ont pas ce flux de manière native.

Si le routage de votre API correspond naturellement aux chemins d'URL et que vous n'avez pas besoin d'une logique de routage complexe en dehors de la structure de répertoires, les fonctions Pages éliminent le besoin d'un Worker distinct avec ses propres routes configurées dans wrangler.toml.

La structure des répertoires et le modèle de middleware

Une structure de projet Pages with Functions réaliste :

/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

Le fichier _middleware.ts est un mécanisme de composition que beaucoup de gens ignorent. Il reçoit la requête avant l'exécution de la fonction spécifique au chemin et peut la court-circuiter avec sa propre réponse ou la transmettre au gestionnaire suivant via ctx.next(). Ceci concerne l'authentification, la journalisation centralisée et CORS sans répéter la logique dans chaque fonction :

// /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; }

Le middleware à la racine /functions couvre toutes les fonctions. Le middleware de la /functions/api couvre uniquement les routes API. Vous pouvez empiler les deux : celui du répertoire parent s'exécute en premier.

Quand les travailleurs purs sont le bon choix

Les fonctions Pages ne prennent pas en charge les déclencheurs cron. Si vous avez besoin d'un travail qui s'exécute à 3 heures du matin pour traiter la facturation, synchroniser un flux externe ou nettoyer les sessions expirées, il doit s'agir d'un Worker autonome avec [triggers] crons sur wrangler.toml. Il n'y a pas d'alternative dans le modèle Pages.

Les consommateurs de file d'attente (les travailleurs qui traitent les messages Cloudflare Queues de manière asynchrone) n'existent pas non plus dans Pages. Si votre architecture utilise des files d'attente pour dissocier les traitements lourds du chemin critique de la requête, le consommateur doit être un Worker distinct.

Workers for Platforms, le mécanisme de répartition des scripts déployés par les utilisateurs (dans le cas d'un SaaS multi-tenant où chaque client a son propre code), est exclusif à Workers. Idem pour les Email Workers, qui reçoivent et traitent les e-mails entrants.

La règle générale : si le déclencheur n'est pas une requête HTTP, il s'agit d'un pur Worker. Les fonctions Pages sont exclusivement HTTP.

Partage de code entre des fonctions et des travailleurs de pages distincts

Une architecture commune utilise à la fois : le projet Pages pour le frontend et l'API principale dans /functions, ainsi que des Workers distincts pour les tâches en arrière-plan. Le problème est que le code métier devra peut-être être partagé : validation des données, accès à la base de données D1, logique d'autorisation.

La solution consiste en des packages npm internes (utilisant des espaces de travail npm/pnpm) ou un travailleur dédié en tant que « couche de service » accessible via la liaison de service par d'autres. Service Binding permet à une fonction Pages d'appeler un Worker directement, sur le même réseau Cloudflare interne, sans frais de réseau et sans passer par l'Internet public :

// /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; }

Le ORDER_PROCESSOR ici est un Worker autonome qui a accès aux files d'attente, aux crons et à toute autre primitive que les fonctions Pages ne prennent pas en charge. Les fonctions Pages se trouvent au niveau de la couche HTTP ; Les travailleurs autonomes sont assis dans des déclencheurs asynchrones. Les deux partagent les liaisons D1 et KV pointant vers les mêmes ressources.

Les critères de décision

Si vous créez un projet avec une interface (tout ce qui génère des actifs statiques lors de la construction), commencez par Pages. Les fonctions que vous ajoutez dans /functions ont exactement la même puissance qu'un Worker autonome pour les cas HTTP. Vous bénéficiez d’un aperçu de branche et d’un pipeline de build intégré sans payer de coûts opérationnels supplémentaires.

Si vous créez un service sans interface frontale, avec des déclencheurs non HTTP ou qui nécessite des environnements nommés avec des liaisons différentes pour la préparation et la production, Workers est le chemin le plus direct. La configuration explicite dans wrangler.toml est plus vérifiable et le modèle de déploiement est plus flexible pour les services backend purs.

Les deux ne s’excluent pas mutuellement. Les projets les plus sérieux aboutissent aux deux : Pages pour ce qui est HTTP et colocalisé avec le frontend, Workers pour ce qui est asynchrone ou planifié.

A lire aussi