Aggregator
L'opposé du Splitter. Plusieurs messages corrélés arrivent dans une fenêtre ; un seul message en sort, consolidé. Le pattern stateful par excellence — et par conséquent le plus délicat à dimensionner.
Problème
En EDI on doit régulièrement consolider des messages reçus séparément : une commande client génère 5 DESADV au fil des jours pendant que les expéditions partent par lots, puis on doit émettre un INVOIC unique regroupant les 5 livraisons en facture mensuelle. Ou encore : un Split de 100 lignes traitées en parallèle doit répondre par un seul statut global à l'émetteur initial. Sans agrégation, on multiplie les messages en aval et on bruite les interlocuteurs.
Forces
- Stateful par nature. Contrairement à la plupart des EIP qui sont stateless, l'aggregator doit retenir les messages partiels jusqu'à complétion. Cela impose un store.
- Complétion non triviale. Quand sait-on qu'on a tout reçu ? Sur taille fixe ? Sur marqueur last explicite ? Sur timeout ? Trois stratégies, trois compromis.
- Backpressure. Un aggregator peut bufferiser indéfiniment si la complétion ne se déclenche pas. Toujours prévoir un seuil et une expiration.
- Ordre indifférent. Le pattern doit fonctionner même si les messages arrivent dans le désordre (5/12, 2/12, 11/12...).
Solution
EIP §268 (Hohpe & Woolf, 2003) modélise l'Aggregator comme
un composant à trois responsabilités : (a) corrélation
— assigner chaque message entrant à un groupe (par exemple par
RFF+ON ou par numéro de commande), (b) accumulation
— stocker les messages du groupe dans un buffer, (c) complétion — décider quand émettre le composite et le
construire à partir des partiels stockés. Une fois le composite émis,
le groupe est purgé.
┌────────────┐
│ DESADV #1 │──┐
└────────────┘ │
┌────────────┐ │ ┌──────────────────────┐
│ DESADV #2 │──┼───▶ │ Aggregator │ ───▶ INVOIC mensuel
└────────────┘ │ │ (correlation = PO) │ consolidé
┌────────────┐ │ │ (completion = J+30) │
│ DESADV #N │──┘ └──────────────────────┘ Stratégies de complétion
Hohpe identifie quatre stratégies courantes :
- Fixed wait. Émettre après un délai fixe (par exemple 30 jours en fin de mois pour la facturation consolidée).
- Wait for all. Émettre quand on a reçu N enfants — utile si le splitter en amont fournit le total dans chaque enfant.
- Timeout. Émettre dès qu'aucun message n'a été reçu dans le groupe pendant T minutes. Robuste mais réactif tardivement.
- External event. Émettre sur un signal externe (fin de période comptable, déclenchement manuel). Pratique pour la facturation mensuelle.
En production, la combinaison wait-for-all + timeout-fallback
est la plus robuste : on attend tous les enfants si possible, mais on
finalise sur timeout pour éviter de bufferiser éternellement un groupe
incomplet.
Implémentation EDI
Trois cas d'usage typiques :
- Facturation consolidée DESADV → INVOIC. Sur une
période mensuelle, agréger tous les DESADV liés à une commande
donnée (corrélation
RFF+ON) puis émettre un INVOIC dont les lignesLINsont la somme des quantités livrées, et leMOA+86est la somme des montants. Très utilisé en grande distribution. - Agrégation de réponses partielles. Un ORDERS éclaté
par site d'entrepôt produit N ORDRSP partiels. L'aggregator
reconstruit un ORDRSP unique pour l'émetteur (corrélation
BGM+RFF+ON, complétion sur compte d'entrepôts attendus). - 997 X12 mensuel. Au lieu de répondre 997 sur chaque
850 reçu, certains partenaires consolident en un 997 quotidien ou
hebdomadaire qui acquitte 100+ groupes fonctionnels d'un coup. La
corrélation se fait alors sur
(émetteur, jour).
UNH+1+INVOIC:D:96A:UN:EAN008'
BGM+380+INV-CONSO-202605+9'
DTM+137:20260514:102'
RFF+ON:PO-12345'
NAD+SU+5412345600015::9'
NAD+BY+8712345600014::9'
LIN+1++4006381333931:EN'
QTY+47:120:PCE' /* total agrégé : 24+48+48 = 120 */
MOA+203:36000:EUR'
LIN+2++4006381444042:EN'
QTY+47:30:PCE'
MOA+203:8500:EUR'
MOA+86:44500:EUR' /* total agrégé */
UNT+12+1'
Lecture : cet INVOIC consolidé porte une seule
RFF+ON (numéro de commande), un seul couple NAD+BY
+ NAD+SU, mais les QTY+47 (Quantity Delivered)
sont sommées sur les DESADV partiels (24+48+48 = 120), et le MOA+86 donne le total agrégé. La complétion est ici
déclenchée par un événement externe (passage en J+30 ou bouton
« facturer » d'un opérateur).
Anti-patterns
- Pas de timeout. Sans expiration, un groupe qui n'atteint jamais la complétion (un message s'est perdu) reste en buffer indéfiniment. Toujours imposer un timeout maximum (J+1 à J+30 selon le flux) avec émission partielle + alerte.
- Corrélation trop large. Si la clé de corrélation est trop générique (par exemple juste « émetteur »), tous les messages tombent dans le même groupe et le composite devient inutilisable. Affiner la clé au minimum nécessaire.
- État en mémoire. Crash de l'instance = pertes des fenêtres ouvertes. Persister.
- Émission sur partial complete sans alerte. Si le timeout déclenche une émission partielle, c'est presque toujours un incident — alerter explicitement, ne pas finaliser en silence.
Patterns liés
- Splitter — le pattern inverse ; souvent les deux sont couplés (split-process-aggregate).
- Flux d'exception — quand un groupe ne complète pas dans la fenêtre.
- Claim Check — pour ne pas dupliquer les gros payloads en buffer.
Sources
- Hohpe G., Woolf B. — Enterprise Integration Patterns, pattern Aggregator (§268). enterpriseintegrationpatterns.com — Aggregator
- Apache Camel — Aggregate EIP, complétion strategies et stateful persistence. camel.apache.org — Aggregate EIP
- EANCOM 2002 — INVOIC Application Guideline. Documentation des règles de facturation consolidée par période et par bon de commande.
- AWS Architecture Blog — Building event-driven architectures with EventBridge Pipes (2023). Application moderne du pattern dans la pile serverless.