[Nom du Binding Cloudflare]
[Nom du Binding Cloudflare]
Documentation technique
Type de ressource : Binding Cloudflare (KV / Queue / R2 / Service / Secret)
Fichier source :services/[worker-name]/wrangler.toml
Statut : [Actif / Déprécié / En développement]
1. Vue d’ensemble
1.1. Description
[Description concise du rôle de ce binding dans l’architecture L3]
1.2. Objectif
- [Objectif principal : ex. stocker temporairement les soumissions de formulaires en cas de panne CRM]
- [Bénéfice pour l’architecture : ex. résilience asynchrone sans bloquer l’utilisateur]
1.3. Caractéristiques
| Propriété | Valeur |
|---|---|
| Type de binding | [KV / Queue / R2 / Service / Secret / D1 / Durable Object] |
| Nom du binding | [BINDING_NAME] |
| Nom de la ressource | [resource-name] |
| Environnements | [Production / Staging / Preview] |
| Workers consommateurs | [Liste des Workers qui utilisent ce binding] |
2. Architecture et flux
2.1. Diagramme de flux
[Worker Producteur] │ • Écriture / Envoi ▼[Binding Cloudflare] │ • Stockage / File d'attente ▼[Worker Consommateur] │ • Lecture / Consommation ▼[Action / Réponse]2.2. Composants impliqués
| Composant | Rôle | Type |
|---|---|---|
| [Worker producteur] | Écriture dans le binding | Worker L3 |
| [Binding] | Stockage / File d’attente | Cloudflare Service |
| [Worker consommateur] | Lecture / Consommation | Worker L3 |
3. Configuration
3.1. Configuration Wrangler (wrangler.toml)
# Exemple pour KV[[kv_namespaces]]binding = "KV_BINDING"id = "your-kv-namespace-id"preview_id = "your-preview-kv-namespace-id"
# Exemple pour Queue (producer)[[queues.producers]]queue = "queue-name"binding = "QUEUE_BINDING"
# Exemple pour Queue (consumer)[[queues.consumers]]queue = "queue-name"max_batch_size = 10max_batch_timeout = 30
# Exemple pour R2[[r2_buckets]]binding = "R2_BUCKET"bucket_name = "bucket-name"preview_bucket_name = "bucket-name-staging"
# Exemple pour Service Binding[[services]]binding = "SERVICE_BINDING"service = "service-name"environment = "production"3.2. Création de la ressource
# Création d'un namespace KVwrangler kv:namespace create "KV_BINDING" --env productionwrangler kv:namespace create "KV_BINDING" --env staging
# Création d'une Queuewrangler queues create queue-name --env productionwrangler queues create queue-name --env staging
# Création d'un bucket R2wrangler r2 bucket create bucket-name
# Liaison d'un bucket R2 à un Workerwrangler r2 bucket link bucket-name --binding R2_BUCKET3.3. Variables d’environnement associées
| Variable | Description | Obligatoire | Valeur par défaut |
|---|---|---|---|
| [Variable] | [Description] | [✅/❌] | [Valeur] |
4. Implémentation
4.1. Interface TypeScript du binding
// Interface Env du Worker consommateurexport interface Env { // KV KV_BINDING: KVNamespace;
// Queue QUEUE_BINDING: Queue;
// R2 R2_BUCKET: R2Bucket;
// Service SERVICE_BINDING: Fetcher;
// Secret SECRET_NAME: string;}4.2. Utilisation dans un Worker producteur
// Exemple : Écriture dans KVawait env.KV_BINDING.put('key', 'value', { expirationTtl: 3600, // 1 heure metadata: { createdAt: new Date().toISOString() }});
// Exemple : Envoi dans une Queueawait env.QUEUE_BINDING.send({ email: 'user@example.com', message: 'Hello', submittedAt: new Date().toISOString()});
// Exemple : Upload vers R2await env.R2_BUCKET.put('path/to/file.jpg', fileContent, { httpMetadata: { contentType: 'image/jpeg' }, customMetadata: { uploadedBy: 'user-123' }});
// Exemple : Appel à un Service Bindingconst response = await env.SERVICE_BINDING.fetch('https://service-name/path', { method: 'POST', body: JSON.stringify({ data: 'value' })});4.3. Utilisation dans un Worker consommateur (Queue)
export default { async queue(batch: MessageBatch, env: Env, ctx: ExecutionContext): Promise<void> { for (const message of batch.messages) { try { const payload = message.body as { email: string; message: string };
// Traitement du message await processMessage(payload, env);
// Acknowledgement implicite (message retiré de la queue) message.ack(); } catch (error) { console.error('Erreur de traitement du message', error);
// Retry ou dead letter queue message.retry(); } } },};5. Cas d’usage spécifiques
5.1. KV : Debouncing de webhooks1/2
Contexte : Le Worker cms-webhook-receiver utilise KV pour éviter les rebuilds multiples en cascade.
// Pose d'un lock pour 2 minutesconst lockKey = 'sanity-rebuild-lock';const isLocked = await env.WEBHOOK_LOCK_KV.get(lockKey);
if (isLocked) { return new Response(JSON.stringify({ status: 'ignored', message: 'Rebuild déjà planifié (Debounced)' }), { status: 200 });}
await env.WEBHOOK_LOCK_KV.put(lockKey, 'locked', { expirationTtl: 120 });5.1. KV : Debouncing de webhooks2/2
Configuration :
- Clé :
sanity-rebuild-lock - TTL : 120 secondes (2 minutes)
- Rationale : Protéger les quotas CI/CD de l’hébergeur
5.2. Queue : Fallback asynchrone pour formulaires1/2
Contexte : Le Worker form-handler utilise une Queue pour re-tenter l’envoi au CRM en cas de panne.
try { const crmRes = await fetch(env.CRM_ENDPOINT_URL, { method: 'POST', headers: { 'Authorization': `Bearer ${env.CRM_API_KEY}` }, body: JSON.stringify(crmPayload), }); if (!crmRes.ok) throw new Error(`Erreur HTTP CRM: ${crmRes.status}`);} catch (crmError) { console.error('Échec de synchro CRM en direct. Envoi en queue...', crmError); await env.SUBMISSIONS_QUEUE.send(crmPayload);}5.2. Queue : Fallback asynchrone pour formulaires2/2
Configuration :
- Nom de la Queue :
form-submissions-queue - Binding :
SUBMISSIONS_QUEUE - Rationale : Résilience asynchrone sans bloquer l’utilisateur
5.3. R2 : Stockage des médias1/2
Contexte : Les Workers media-upload, media-cleanup et sanity-backup utilisent R2 pour stocker les médias et les backups.
// Upload d'un médiaawait env.R2_BUCKET.put(`medias/images/blog/${Date.now()}-${filename}`, fileContent, { httpMetadata: { contentType: 'image/webp' }});
// Listing des objetsconst objects = await env.R2_BUCKET.list({ prefix: 'medias/' });
// Suppressionawait env.R2_BUCKET.delete('medias/images/blog/old-image.webp');
// Streaming vers R2 (backup)await env.R2_BACKUP_BUCKET.put(backupKey, exportRes.body, { customMetadata: { exportedAt: new Date().toISOString() }});5.3. R2 : Stockage des médias2/2
Configuration :
- Bucket médias :
pub-medias - Bucket backups :
backups-sanity - Rationale : Stockage Edge natif, coûts maîtrisés, performance optimale
6. Sécurité et accès
6.1. Contrôle d’accès
| Binding | Accès | Rationale |
|---|---|---|
| KV | Workers uniquement | Pas d’accès direct depuis le client |
| Queue | Workers uniquement | Pas d’accès direct depuis le client |
| R2 | Workers + URLs publiques/signées | Médias publics, documents sensibles signés |
| Secrets | Workers uniquement | Jamais exposés côté client |
6.2. Règles de sécurité
- ✅ Les bindings sont accessibles uniquement depuis les Workers (pas depuis le navigateur)
- ✅ Les secrets sont injectés via
wrangler secret put(jamais dans le code source) - ✅ Les buckets R2 publics sont protégés par le proxy Cloudflare (WAF, DDoS)
- ✅ Les URLs signées ont une durée de vie limitée (1h à 24h max)
- ✅ Les Queues ne sont pas accessibles publiquement ( Workers uniquement)
6.3. Rotation des secrets
# Rotation d'un secretwrangler secret put SECRET_NAME --env productionwrangler secret put SECRET_NAME --env staging
# Liste des secretswrangler secret list --env production7. Performance et limites
7.1. Limites par type de binding
| Binding | Limite | Rationale |
|---|---|---|
| KV | 100 000 lectures/s, 1 000 écritures/s | Quota Cloudflare |
| Queue | 5 000 messages/s, 10 MB max par message | Quota Cloudflare |
| R2 | 10 000 000 requêtes/mois (Free), Illimité (Paid) | Quota Cloudflare |
| Service Binding | 50 sous-requêtes par Worker | Limite Workers |
7.2. Optimisations appliquées
- ✅ Utiliser KV pour les données fréquemment lues et rarement modifiées
- ✅ Utiliser les Queues pour le traitement asynchrone (évite les timeouts)
- ✅ Utiliser R2 pour le stockage de fichiers (pas de limite de taille)
- ✅ Utiliser le streaming HTTP pour les gros volumes (évite OOM)
- ✅ Mettre en cache les données KV avec TTL approprié
7.3. Coûts
| Binding | Modèle de coût | Estimation mensuelle |
|---|---|---|
| KV | $0.50/10M lectures, $5/1M écritures | ~$5-10 |
| Queue | $0.40/1M messages | ~$2-5 |
| R2 | $0.015/GB/mois, $0.36/1M requêtes | ~$10-20 |
| Service Binding | Inclus dans le coût Workers | $0 supplémentaire |
8. Monitoring et observabilité
8.1. Métriques clés
| Binding | Métrique | Seuil d’alerte | Canal |
|---|---|---|---|
| KV | Latence p95 | > 50ms | Slack |
| Queue | Profondeur de la queue | > 1000 messages | PagerDuty |
| Queue | Taux d’erreur | > 5% sur 5 min | Slack |
| R2 | Espace utilisé | > 80% du quota | |
| R2 | Coût mensuel | > $50 |
8.2. Commandes de debug
# Inspection KVwrangler kv:key list --binding=KV_BINDING --env productionwrangler kv:key get --binding=KV_BINDING "key" --env production
# Inspection Queuewrangler queues info queue-name --env production
# Inspection R2wrangler r2 object list bucket-name --prefix medias/
# Logs en temps réelwrangler tail [worker-name] --env production9. Débogage et troubleshooting
9.1. Problèmes courants
| Symptôme | Cause probable | Solution |
|---|---|---|
| “Binding not found” | Binding mal configuré dans wrangler.toml | Vérifier la configuration et redéployer |
| “Queue full” | Consommateur trop lent | Augmenter max_batch_size ou ajouter des consommateurs |
| “KV rate limit exceeded” | Trop de lectures/écritures | Mettre en cache ou optimiser les accès |
| “R2 access denied” | Permissions insuffisantes | Vérifier les permissions du token API |
| “Secret not found” | Secret non injecté | Exécuter wrangler secret put |
9.2. Tests manuels
# Test KVwrangler kv:key put --binding=KV_BINDING "test-key" "test-value" --env stagingwrangler kv:key get --binding=KV_BINDING "test-key" --env staging
# Test Queue (envoi manuel)wrangler queues send queue-name --data '{"test": "data"}' --env staging
# Test R2wrangler r2 object put bucket-name/test.txt --file=test.txtwrangler r2 object get bucket-name/test.txt10. Bonnes pratiques
10.1. Architecture
- ✅ Utiliser KV pour les données temporaires (locks, cache, sessions)
- ✅ Utiliser les Queues pour le traitement asynchrone (formulaires, webhooks)
- ✅ Utiliser R2 pour le stockage de fichiers (médias, backups)
- ✅ Séparer les buckets par environnement (production, staging)
- ✅ Documenter les bindings dans ce fichier
10.2. Code
- ✅ Typer strictement les bindings dans l’interface Env
- ✅ Gérer les erreurs de manière explicite (try/catch)
- ✅ Utiliser le streaming pour les gros volumes (R2)
- ✅ Mettre en cache les données KV avec TTL approprié
- ✅ Logger les opérations critiques pour l’audit
10.3. Performance
- ✅ Minimiser les lectures/écritures KV (batch si possible)
- ✅ Utiliser les Queues pour éviter les timeouts
- ✅ Utiliser le streaming HTTP pour R2 (évite OOM)
- ✅ Surveiller les métriques de performance (latence, débit)
- ✅ Optimiser les coûts (nettoyage régulier, lifecycle rules)
10.4. Sécurité
- ✅ Ne jamais exposer les bindings côté client
- ✅ Injecter les secrets via
wrangler secret put - ✅ Rotation régulière des secrets (tous les 90 jours)
- ✅ Utiliser des URLs signées pour les documents sensibles
- ✅ Auditer les accès aux buckets R2
11. Évolutions et roadmap
11.1. Améliorations planifiées
- [Évolution 1 : ex. Migration vers D1 pour les données relationnelles]
- [Évolution 2 : ex. Ajout de Durable Objects pour les sessions utilisateur]
- [Évolution 3 : ex. Implémentation d’une dead letter queue pour les messages échoués]
11.2. Limitations connues
- ❌ KV ne supporte pas les transactions (pas d’atomicité multi-clés)
- ❌ Les Queues ont une limite de 10 MB par message
- ❌ R2 ne supporte pas nativement la transformation d’images (nécessite Cloudflare Images)
- ❌ Les Service Bindings ont une limite de 50 sous-requêtes par Worker
12. Ressources liées1/3
- Documentation Cloudflare KV : Getting Started
- Documentation Cloudflare Queues : Getting Started
- Documentation Cloudflare R2 : Getting Started
- Documentation Service Bindings : Workers Services
- DAT L3 : §5 - Microservices Métiers (Cloudflare Workers Dédiés)
- DAT L3 : §6 - Structure Monorepo, Wrangler & Configuration
12. Ressources liées2/3
- Workers consommateurs :
services/form-handler/services/cms-webhook-receiver/services/media-upload/services/media-cleanup/services/sanity-backup/
12. Ressources liées3/3
- Fichiers concernés :
services/[worker-name]/wrangler.toml- Configuration Dashboard Cloudflare → KV / Queues / R2
13. Historique des modifications1/2
| Date | Version | Description | Auteur |
|---|---|---|---|
| YYYY-MM-DD | 1.0 | Création initiale | [Nom] |
| YYYY-MM-DD | 1.1 | [Modification] | [Nom] |
13. Historique des modifications2/2
---
**Points clés de ce template :**- Couvre tous les types de bindings Cloudflare (KV, Queue, R2, Service, Secret)- Détaille la configuration Wrangler complète pour chaque type- Inclut des cas d'usage spécifiques au projet (debouncing webhooks, fallback formulaires, stockage médias)- Documente les limites, les coûts et les optimisations- Fournit les commandes de debug et de monitoring- Sépare clairement les bonnes pratiques par catégorie (architecture, code, performance, sécurité)