Skip to content

Type de ressource : Cloudflare Worker (Microservice FaaS)
Fichier source : services/form-handler/src/index.ts
Statut : Actif

Worker Cloudflare pour la validation et la mise en queue des soumissions de formulaire. Valide les donnĂ©es entrantes via Zod, crĂ©e un objet de soumission avec mĂ©tadonnĂ©es, et l’envoie dans la Queue Cloudflare pour un traitement asynchrone.

  • Valider les soumissions de formulaire cĂŽtĂ© serveur
  • DĂ©coupler la validation du traitement asynchrone
  • Utiliser une Queue Cloudflare pour le traitement en arriĂšre-plan
  • Fournir une rĂ©ponse immĂ©diate au frontend
Propriété Valeur
Type Microservice métier
Trigger HTTP fetch
Route publique /api/submit, /health
Environnements Development, Production
Consommateurs Astro (frontend), Submission-processor (Queue consumer)
[Entrée : Astro / Navigateur]
│ ‱ POST /api/submit
▌
[Form Handler Worker]
│ ‱ Validation Zod (name, email, message)
│ ‱ CrĂ©ation de l'objet de soumission
│ ‱ Envoi dans la Queue
▌
[Queue Cloudflare (submissions-queue)]
│
▌
[Submission-processor Worker]
│ ‱ CrĂ©ation du document Sanity
▌
[Sanity CMS]
[Client]
│
▌
[Astro Frontend]
│ ‱ POST /api/submit
▌
[Form Handler Worker]
│
▌
[Queue Cloudflare]
│
▌
[Submission-processor Worker]
│
▌
[Sanity CMS]
Composant RĂŽle Type
Zod Validation des entrées BibliothÚque
SUBMISSIONS_QUEUE Queue asynchrone Cloudflare Binding
Submission-processor Consommateur de la Queue Cloudflare Worker
Sanity API Stockage des soumissions Service tiers
Variable Description Obligatoire Valeur par défaut
ENVIRONMENT Environnement (dev/production) ✅ dev
Binding Type Nom Description
SUBMISSIONS_QUEUE Queue SUBMISSIONS_QUEUE Queue pour les soumissions
services/form-handler/wrangler.toml
name = "amn-form-handler"
main = "src/index.ts"
compatibility_date = "2025-07-18"
compatibility_flags = ["nodejs_compat"]
[vars]
ENVIRONMENT = "dev"
[[queues.producers]]
queue = "submissions-queue-dev"
binding = "SUBMISSIONS_QUEUE"
[env.dev]
name = "amn-form-handler-dev"
vars = { ENVIRONMENT = "dev" }
[[env.dev.queues.producers]]
queue = "submissions-queue-dev"
binding = "SUBMISSIONS_QUEUE"
[env.production]
name = "amn-form-handler-prod"
vars = { ENVIRONMENT = "production" }
[[env.production.queues.producers]]
queue = "submissions-queue-prod"
binding = "SUBMISSIONS_QUEUE"

Aucun secret n’est injectĂ© dans ce service.

import { z } from 'zod'
// Schema validation for form submission
const SubmissionSchema = z.object({
name: z.string().min(2).max(100),
email: z.string().email(),
message: z.string().min(10).max(2000),
})
export interface Env {
SUBMISSIONS_QUEUE: Queue;
ENVIRONMENT: string;
}
export default {
async fetch(request: Request, env: Env): Promise<Response> {
const url = new URL(request.url);
// Handle CORS preflight
if (request.method === 'OPTIONS') {
return handleCors();
}
// Handle POST requests for form submission
if (request.method === 'POST' && url.pathname === '/api/submit') {
return handleSubmit(request, env);
}
// Health check endpoint
if (request.method === 'GET' && url.pathname === '/health') {
return new Response(JSON.stringify({
status: 'healthy',
environment: env.ENVIRONMENT,
timestamp: new Date().toISOString()
}), {
headers: { 'Content-Type': 'application/json' },
});
}
return new Response('Not Found', { status: 404 });
},
};
async function handleSubmit(request: Request, env: Env): Promise<Response> {
try {
const body = await request.json();
// Validate input
const validatedData = SubmissionSchema.parse(body);
// Create submission object with metadata
const submission = {
...validatedData,
submittedAt: new Date().toISOString(),
id: crypto.randomUUID(),
environment: env.ENVIRONMENT,
};
// Send to queue for async processing
await env.SUBMISSIONS_QUEUE.send(submission);
// Return immediate success response
return new Response(JSON.stringify({
success: true,
message: 'Form submitted successfully',
id: submission.id,
}), {
headers: {
'Content-Type': 'application/json',
...corsHeaders(),
},
});
} catch (error) {
if (error instanceof z.ZodError) {
return new Response(JSON.stringify({
success: false,
error: 'Validation failed',
details: error.issues,
}), {
status: 400,
headers: {
'Content-Type': 'application/json',
...corsHeaders(),
},
});
}
console.error('Submission error:', error);
return new Response(JSON.stringify({
success: false,
error: 'Internal server error',
}), {
status: 500,
headers: {
'Content-Type': 'application/json',
...corsHeaders(),
},
});
}
}
function corsHeaders(): Record<string, string> {
return {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'POST, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type',
};
}
function handleCors(): Response {
return new Response(null, {
status: 204,
headers: corsHeaders(),
});
}
// Schema Zod
const SubmissionSchema = z.object({
name: z.string().min(2).max(100),
email: z.string().email(),
message: z.string().min(10).max(2000),
});
// Interface des bindings
export interface Env {
SUBMISSIONS_QUEUE: Queue;
ENVIRONMENT: string;
}
// Type de soumission
type Submission = {
name: string;
email: string;
message: string;
submittedAt: string;
id: string;
environment: string;
};
Mécanisme Implémentation Rationale
Validation Zod Validation stricte des entrées Prévention des injections
CORS Headers CORS permissifs Permettre les requĂȘtes cross-origin
Aucun secret Pas de secret injecté Pas de données sensibles dans ce service
  • ✅ Validation Zod du nom (min 2, max 100)
  • ✅ Validation Zod de l’email (format email)
  • ✅ Validation Zod du message (min 10, max 2000)

Non applicable - aucun secret n’est utilisĂ© dans ce service.

Scénario Stratégie Rationale
Queue failure Pas de retry Simple retry dans le Queue consumer

Non implémenté - pas de lock configuré.

  • ✅ Timeout global : DĂ©pend de Cloudflare (30s Free / 50s Paid)
  • ✅ Timeout par service tiers : DĂ©pend de Cloudflare
Limite Valeur StratĂ©gie d’optimisation
Mémoire RAM 128 MB Pas de traitement lourd en mémoire
CPU time 30s (Free) / 50s (Paid) Validation rapide
Nombre de sous-requĂȘtes 50 Pas de sous-requĂȘtes
Taille requĂȘte/rĂ©ponse 100 MB Payload de formulaire limitĂ©
  • ✅ Validation rapide (Zod)
  • ✅ Mise en queue asynchrone (pas d’attente pour le traitement)
  • ✅ Pas de chargement en mĂ©moire

Non implémenté - logs console.error basiques.

Non implĂ©mentĂ© - aucune mĂ©trique ou alerte n’est configurĂ©e.

Terminal window
# Logs en temps réel
wrangler tail form-handler
# Vérification des bindings
wrangler deployments list
Terminal window
# Build
npm run build --workspace=services/form-handler
# Déploiement staging
wrangler deploy --env staging
# Déploiement production
wrangler deploy --env production
Terminal window
# Liste des déploiements
wrangler deployments list
# Rollback vers une version précédente
wrangler deployments rollback --deployment-id=[id]
Terminal window
# Test HTTP
curl -X POST http://localhost:8789/api/submit \
-H "Content-Type: application/json" \
-d '{"name":"Test","email":"test@example.com","message":"Test message"}'
# Test health check
curl http://localhost:8789/health
SymptĂŽme Cause probable Solution
Validation échoue Données invalides Vérifier les rÚgles Zod
Queue non disponible Binding mal configuré Vérifier wrangler.toml
CORS error Headers CORS manquants Vérifier la configuration CORS
Code HTTP / Erreur Signification Action
400 Validation échouée Corriger les données du formulaire
500 Erreur serveur Vérifier les logs du Worker
  • ✅ DĂ©coupler la validation du traitement asynchrone
  • ✅ Utiliser les bindings Cloudflare plutĂŽt que des appels HTTP internes
  • ✅ ResponsabilitĂ© unique (validation et mise en queue)
  • ✅ Typer strictement les bindings et les rĂ©ponses
  • ✅ Valider toutes les entrĂ©es (Zod)
  • ✅ GĂ©rer explicitement les erreurs (try/catch)
  • ✅ Logger les erreurs
  • ✅ Valider toutes les entrĂ©es cĂŽtĂ© serveur
  • ✅ Utiliser Zod pour la validation
  • ✅ Validation rapide
  • ✅ Mise en queue asynchrone
  • Configuration de Logpush pour les logs
  • Ajout de mĂ©triques et alertes
  • Ajout de rate limiting
  • AmĂ©lioration de la validation (CAPTCHA)
  • ❌ CORS permissif (*) - Ă  restreindre pour la production
  • ❌ Pas de rate limiting
  • ❌ Pas de logs structurĂ©s
  • ❌ Pas de monitoring configurĂ©
  • Documentation Cloudflare Workers : Getting Started
  • Documentation Cloudflare Queues : Queues
  • Documentation Zod : Zod
  • Workers associĂ©s :
    • submission-processor
  • Fichiers concernĂ©s :
    • services/form-handler/src/index.ts
    • services/form-handler/wrangler.toml
    • services/form-handler/package.json
Date Version Description Auteur
2026-09-15 1.0 Création initiale Devin
Edit page

Last updated: