Routing Slip
L'itinéraire voyage avec le message. Pas d'orchestrateur central, pas de coordinateur stateful : le message liste lui-même les étapes à traverser, chaque filtre lit l'étape suivante, transmet au canal indiqué. Le pattern le plus pur de la chorégraphie distribuée.
Problème
Un message doit traverser une séquence d'étapes qui dépend de son type ou de son contenu : un EDIFACT INVOIC d'un fournisseur français pour un buyer allemand passe par parse → validate → enrich GLN → translate UBL → sign XAdES → ship via PEPPOL. Un X12 810 américain passe par parse → validate → translate IDoc → ship to ERP. Si chaque étape doit savoir « où envoyer ensuite » en fonction du type, le code devient un graphe spaghetti. Coder un Process Manager centralisé pour chaque variation crée trop de couplage. Il faut une approche où l'itinéraire est donné en début et exécuté par les étapes.
Forces
- Stateless par étape. Chaque filtre lit le slip, fait son travail, passe le message à l'étape suivante. Pas d'état persistant.
- Itinéraire dynamique. Le slip est construit au moment de l'arrivée du message ; deux messages similaires peuvent prendre des routes différentes.
- Pas de single point of orchestration. La panne d'un coordinateur central ne fige pas le système.
- Observabilité dégradée. Sans coordinateur, personne ne sait où en est un message à l'instant t — il faut complémenter par un Message History.
Solution
EIP §301 (Hohpe & Woolf, 2003) définit le Routing Slip comme un en-tête de message portant une liste ordonnée d'étapes à traverser. À l'arrivée, un dispatcher initial calcule le slip selon le type et le contenu, et l'attache au message. Chaque composant qui traite le message : (a) lit la première étape du slip, (b) effectue son travail, (c) retire l'étape du slip, (d) envoie le message sur le canal correspondant à la prochaine étape. Quand le slip est vide, le message arrive à destination finale.
Le message porte sa propre itinéraire :
{ payload, slip: [step1, step2, step3, step4] }
│
▼
┌─────────┐ pop step1
│ step1 │ ──▶ { payload', slip: [step2, step3, step4] }
└─────────┘
│
▼
┌─────────┐ pop step2
│ step2 │ ──▶ { payload'', slip: [step3, step4] }
└─────────┘
│
▼
(etc.) Implémentation EDI
L'exemple canonique en EDI : cXML PunchOut.
Quand un acheteur lance un PunchOut depuis son ERP vers le
catalogue d'un fournisseur, il envoie un
PunchOutSetupRequest qui contient son URL de retour
embarquée — c'est une slip à une seule étape : « quand
tu as fini ton catalogage, renvoie-moi à cette URL avec le panier
construit ». Le fournisseur n'a aucune connaissance préalable
du buyer ; tout est dans le message.
<?xml version="1.0"?>
<cXML payloadID="2026-05-14T12:00:00@buyer.example.com"
timestamp="2026-05-14T12:00:00-00:00">
<Header>
<From><Credential domain="NetworkID"><Identity>BUYER</Identity></Credential></From>
<To><Credential domain="NetworkID"><Identity>SUPPLIER</Identity></Credential></To>
<Sender><Credential domain="NetworkID"><Identity>BUYER</Identity></Credential>
<UserAgent>Ediverse Punchout/1.0</UserAgent>
</Sender>
</Header>
<Request>
<PunchOutSetupRequest operation="create">
<BuyerCookie>SESSION-9f2b1a73</BuyerCookie>
<Extrinsic name="UserEmail">jane@buyer.example.com</Extrinsic>
<BrowserFormPost>
<!-- THE routing slip : où le supplier devra renvoyer l'utilisateur -->
<URL>https://buyer.example.com/punchout/return?session=SESSION-9f2b1a73</URL>
</BrowserFormPost>
</PunchOutSetupRequest>
</Request>
</cXML>
Lecture : le champ <BrowserFormPost><URL>
est la routing slip cXML. Le supplier ne stocke pas où renvoyer
l'utilisateur ; il lit cette URL dans le message. Une fois le
panier construit côté supplier, il génère un
PunchOutOrderMessage qu'il POST vers cette URL ;
l'utilisateur revient sur le site buyer avec son panier prêt à
être converti en commande formelle.
Autres usages EDI :
- Slip de pipeline contextuel. Un message reçu
via AS2 d'un partenaire X est tagué avec
routing-slip = [parse-x12-850, enrich-gln, translate-idoc850, ship-sap]; le même partenaire en mode UBL/AS4 reçoit[parse-ubl, validate-peppol, translate-idoc850, ship-sap]. Aucun composant central n'arbitre. - SBDH étendu. Un Standard Business Document Header peut transporter des extensions qui jouent le rôle de routing slip : liste des destinataires suivants après certains traitements (en mode PEPPOL multi-corner).
- Pipeline as data. Pour faciliter le test d'intégration et le rejeu, certains hubs mettent toute la route dans le message à l'arrivée — testable comme un flux unitaire.
Routing slip vs. process manager
Deux approches duales pour orchestrer une séquence :
- Process Manager — état centralisé, machine à états explicite, escalades pilotées, observabilité native, mais couplage à un composant central et état persistant.
- Routing Slip — état dans le message, pas de coordinateur, scalabilité plate, mais observabilité fragile (besoin de Message History) et compensation moins naturelle.
Choix selon le profil : cycles courts (< quelques minutes), variations multiples par type, faible besoin d'audit en temps réel → routing slip. Cycles longs (jours/mois), timers et escalades, besoin de dashboards opérateur → process manager.
Anti-patterns
- Slip muet. Un message sans slip qui tombe sur un filtre : aucun moyen de décider la suite. Toujours attacher au point d'entrée, pas plus tard.
- Slip non versionné. Les noms d'étapes changent avec le temps ; un slip généré il y a 6 mois peut pointer vers une étape qui n'existe plus. Versionner.
- Étape qui modifie l'avenir. Une étape qui ajoute des étapes au slip transforme le pattern en routing table dynamique non-prouvable. Garder la slip immuable sauf cas explicitement modélisés.
- Pas de Message History. Sans trace de ce qui s'est passé, le débogage d'un slip cassé est cauchemardesque. Coupler systématiquement.
Patterns liés
- Process Manager — l'alternative centralisée stateful.
- Message History — couplage quasi-obligatoire pour l'observabilité.
- Pipes and Filters — chaque étape du slip est un filtre.
- Content-Based Router — un routeur qui inspecte la slip est en fait un routing slip executor.
Sources
- Hohpe G., Woolf B. — Enterprise Integration Patterns, pattern Routing Slip (§301). enterpriseintegrationpatterns.com — Routing Slip
- cXML Reference Guide, Ariba (SAP). Documentation formelle de PunchOutSetupRequest / PunchOutOrderMessage, exemple canonique de slip embarqué. cxml.org
- Apache Camel — Routing Slip EIP. Implémentation de référence open-source. camel.apache.org — Routing Slip
- UN/CEFACT — SBDH. Le Standard Business Document Header autorise des extensions BusinessScope qui peuvent encoder un slip multi-cibles.