Découvrir une norme

Arazzo
le contrat d'API du parcours

Chaque API a son contrat. Le parcours qui les enchaîne n'en a pas.

DEGODEZ Sébastien · Communauté AXA

Photo de DEGODEZ Sébastien
Qui suis-je ?
DEGODEZ Sébastien
  • Staff Engineer chez AXA
  • Maintainer Microcks — projet CNCF Incubating
  • Auteur de skraft — pipeline SDLC agentique open source
45 minutes

Au programme

  1. Le problèmePourquoi les contrats d'API ne suffisent pas5 min
  2. ArazzoDéfinition, état des lieux, lire un fichier15 min
  3. Un exempleUn parcours complet, avec dependsOn10 min
  4. Une hypothèseMicrocks V2, sur prototype10 min
  5. ÉchangeVotre avis, vos parcours5 min

En sortant, vous saurez ce qu'est Arazzo, lire un fichier, et vous aurez donné votre avis sur une idée.

01 · Le problème

Une souscription habitation s'appuie sur 3 contrats d'API.
Le parcours qui les enchaîne, lui, n'est décrit nulle part.

Dans quel ordre appeler ? Quelle donnée passe d'un appel au suivant ? Que faire si un appel échoue ? Aujourd'hui : un wiki, un diagramme de séquence qui vieillit, ou la tête d'un architecte.

01 · Le problème

Des contrats d'API par service, aucun pour le parcours

Vue
Le parcours ? wiki · Confluence · séquence PlantUML · tête de l'archi ? ? Contrat Arazzo · workflow souscrireHabitation ordre des étapes · données échangées · critères de succès · reprises — versionné dans git quoteId paymentId API Devis POST /quotes contrat OpenAPI ✓ API Paiement POST /payments contrat OpenAPI ✓ API Police POST /policies contrat OpenAPI ✓

02 · Définition

Arazzo, c'est quoi ?

Une norme de l'OpenAPI Initiative (Linux Foundation) pour décrire, en YAML ou JSON, une suite d'appels d'API : leur ordre, les données qui passent de l'un à l'autre, et ce qui fait qu'une étape est réussie.

arazzo « tapisserie » en italien — on tisse des API existantes en un parcours.

Lisible

Un format structuré (YAML ou JSON), relu en PR comme du code.

Déterministe

Même entrée, mêmes étapes, mêmes critères. Pas d'interprétation.

Spécifié

Chaque étape déclare son critère de succès : « réussi » est écrit, pas supposé.

02 · Définition

Ce qu'Arazzo est — et ce qu'il n'est pas

C'est

  • Un contrat : la description de référence d'un parcours.
  • Une couche au-dessus d'OpenAPI et d'AsyncAPI, qu'il référence.
  • Un fichier versionné dans git, revu en PR.
  • Une spécification : ordre, données échangées, critères de succès, reprises.

Ce n'est pas

  • Un orchestrateur : il ne tourne pas en production (ni BPMN, ni Temporal, ni saga).
  • Un remplaçant d'OpenAPI / AsyncAPI : sans eux, il n'a rien à référencer.
  • Un programme : il spécifie, il n'exécute rien.
  • Un diagramme : c'est une spécification structurée, versionnée et relue.
03 · État des lieux — octobre 2026

Trois normes, trois questions

NormeRépond àVersionCe qui compte pour nous
OpenAPIQue fait cet appel HTTP ?3.2.0 sept. 2025QUERY, streaming (text/event-stream, jsonl), tags hiérarchiques. Sans rupture vs 3.1.
AsyncAPIQuel message circule sur ce canal ?3.1.0 janv. 2026La 3.0 a séparé canaux et opérations send/receive. La 3.1 est mineure.
ArazzoDans quel ordre, avec quelles données, et quand est-ce réussi ?1.1.0 mai 2026La 1.1 ajoute les étapes AsyncAPI : REST et événements dans un même parcours.
03 · État des lieux

Arazzo ne remplace rien : il référence

Arazzo — le contrat du parcours sourceDescriptions · workflows · steps · successCriteria · outputs operationId operationId · action OpenAPI — synchrone createQuote · pay · issuePolicy AsyncAPI — événements receive policy.issued Nos services : .NET, Java, Kafka, API Gateway…

Corollaire : pas de contrat OpenAPI/AsyncAPI à jour, pas d'Arazzo.

03 · État des lieux

Une norme jeune, une famille mature

2017
OpenAPI 3.0
Swagger devient une norme ouverte.
2021
OpenAPI 3.1
Alignement JSON Schema.
déc. 2023
AsyncAPI 3.0
send / receive séparés des canaux.
mai 2024
Arazzo 1.0
Workflows REST.
sept. 2025
OpenAPI 3.2
QUERY, streaming.
janv. 2026
AsyncAPI 3.1
Mineure.
mai 2026
Arazzo 1.1
+ étapes AsyncAPI.

Même gouvernance qu'OpenAPI : OpenAPI Initiative, Linux Foundation.

04 · Lire un fichier

Anatomie : chaque bloc répond à une question

Bloc
Question
Exemple
sourceDescriptions
Avec quels contrats d'API ?
quote-api.openapi.yaml, policy-events…
workflows
Quel parcours ?
souscrireHabitation
dependsOn
Quel parcours doit passer avant ?
identifierClient
inputs
De quoi a-t-il besoin ?
address (JSON Schema)
steps
Quelles étapes, dans quel ordre ?
creerDevis → verifierEligibilite → …
operationId
Quel appel ?
createQuote dans quoteApi
parameters · requestBody
Avec quelles données ?
$steps.creerDevis.outputs.quoteId
successCriteria
C'est réussi quand ?
$statusCode == 201
onSuccess · onFailure
Et ensuite ? Et si ça échoue ?
retry ×3, goto, end
dependsOn
Quelle étape doit être faite avant ?
payer après verifierEligibilite
outputs
Que transmet l'étape ?
quoteId ← $response.body#/id
outputs
Que produit le parcours ?
policyId
components
Qu'est-ce qui se réutilise ?
paramètres, actions de reprise
04 · Lire un fichier

Les expressions : le fil qui relie les étapes

ExpressionLit…Exemple
$inputs.xune entrée du workflow$inputs.customerId
$statusCodele code HTTP de la réponse$statusCode == 201
$response.body#/…un champ de la réponse (JSON Pointer)$response.body#/id
$steps.s.outputs.yune sortie d'une étape précédente$steps.creerDevis.outputs.quoteId
$workflows.w.outputs.yune sortie d'un autre workflow$workflows.identifierClient.outputs.customerId
$sourceDescriptions.n.opune opération d'un contrat d'API$sourceDescriptions.quoteApi.createQuote

À retenir : $steps.…outputs rend explicite ce qu'on se transmet entre équipes.

05 · Un exemple complet

Du devis à la police, en un workflow

Scénario
onFailure: retry ×3 (2 s) workflow identifierClient → customerId dependsOn step 1 creerDevis POST /quotes → quoteId step 2 verifierEligibilite POST …/eligibility → eligible == true step 3 payer POST /payments → paymentId step 4 emettrePolice POST /policies → policyId dependsOn: [verifierEligibilite] ✓ policyId dependsOn non respecté payer appelé avant verifierEligibilite

05 · Un exemple complet

Le fichier : sources et premières étapes

souscription-habitation.arazzo.yamlArazzo 1.1.0
arazzo: 1.1.0
sourceDescriptions:                                       # les contrats d'API, référencés
  - { name: quoteApi,   type: openapi, url: ./quote-api.openapi.yaml }
  - { name: paymentApi, type: openapi, url: ./payment-api.openapi.yaml }
  - { name: policyApi,  type: openapi, url: ./policy-api.openapi.yaml }
workflows:
  - workflowId: identifierClient                            # étapes non détaillées ici
  - workflowId: souscrireHabitation
    dependsOn: [ identifierClient ]                         # un parcours prérequis
    steps:
      - stepId: creerDevis
        operationId: $sourceDescriptions.quoteApi.createQuote
        requestBody:
          payload: { customerId: $workflows.identifierClient.outputs.customerId }
        successCriteria: [ { condition: $statusCode == 201 } ]
        outputs: { quoteId: $response.body#/id }
      - stepId: verifierEligibilite
        operationId: $sourceDescriptions.quoteApi.checkEligibility
        parameters: [ { name: id, in: path, value: $steps.creerDevis.outputs.quoteId } ]
        successCriteria: [ { condition: $response.body#/eligible == true } ]
clé structure Arazzo$… expression# … commentaire
05 · Un exemple complet

dependsOn : un prérequis écrit dans le contrat

… suite du workflowdependsOn d'étape
- stepId: payer
  operationId: $sourceDescriptions.paymentApi.pay
  # prérequis explicite. Selon la spec Arazzo,
  # en synchrone l'ordre de steps suffit : dependsOn
  # sert surtout à l'asynchrone (voir annexe).
  dependsOn: [ verifierEligibilite ]   # jamais avant
  requestBody:
    payload: { quoteId: $steps.creerDevis.outputs.quoteId }
  successCriteria: [ { condition: $statusCode == 201 } ]
  onFailure:
    - { name: indispo, type: retry,
        retryAfter: 2, retryLimit: 3,
        criteria: [ { condition: $statusCode == 503 } ] }
  outputs: { paymentId: $response.body#/id }
- stepId: emettrePolice
  operationId: $sourceDescriptions.policyApi.issuePolicy
  successCriteria: [ { condition: $statusCode == 201 } ]
  outputs: { policyId: $response.body#/policyId }

Entre workflows

Composer des parcours : souscrireHabitation après identifierClient.

Entre étapes

Une règle métier devient contractuelle : on ne paie pas avant l'éligibilité. Réordonner le fichier ne peut plus la casser en silence.

Nuance de la spec

En synchrone, l'ordre du tableau steps suffit. dependsOn sert surtout à l'asynchrone et à expliciter un prérequis.

06 · Esprit critique

Pourquoi y aller — et ce qui peut coincer

Ce qu'on gagne

  • Une source de vérité du parcours, revue en PR avec les contrats d'API.
  • Spécifié : ordre, données et critères de succès écrits noir sur blanc.
  • Norme ouverte (OpenAPI Initiative) : pas de verrou éditeur.
  • Partagé : archis, devs et QA lisent le même fichier.
  • REST + Kafka dans un même parcours depuis la 1.1.

Ce qui peut coincer

  • Norme jeune : la 1.1 date de mai 2026, peu de retours d'expérience.
  • Prérequis : sans contrats d'API à jour, l'Arazzo ment.
  • Maintenance : un fichier de plus. Qui en est propriétaire ?
  • Hors norme : les jeux de données ne sont pas couverts par la spec.
Mon parti pris : commencer par un parcours critique, multi-équipes, qui casse en recette. Si en 3 mois il n'a pas clarifié le parcours entre les équipes, on arrête.
Prototype · pas une version de Microcks
07 · Une hypothèse pour Microcks V2

Et si demain, Microcks vérifiait que nos applications respectent leurs workflows Arazzo ?

Pas une release

Aucune version de Microcks ne fait ça aujourd'hui.

Pas une roadmap

Rien n'est décidé par le projet Microcks.

Un prototype

Sur mon fork personnel, pour tester l'idée — et recueillir votre avis.

Prototype · pas une version de Microcks
07 · Hypothèse — Microcks V2

L'idée : un fichier, deux façons de vérifier

Arazzo OpenAPI AsyncAPI import · liaison nom + version Microcks V2 ? le workflow devient un objet testable rejoue les étapes diagramme · résultat · historique Sur les mocks je code sans attendre les autres Sur l'application je prouve que je le respecte CI → API Microcks
Prototype · pas une version de Microcks
07 · Ce que montre le prototype

Microcks lirait le workflow

Prototype Capture du prototype Microcks : un workflow Arazzo importé, affiché en diagramme avec une étape REST createOrder, puis deux étapes événement requestShipping et confirmOrder, et les données qui circulent entre elles.
Clic ou touche Z : capture complète

Ce qu'on voit

  • Le fichier Arazzo importé, relié à ses contrats d'API.
  • Les étapes REST et événement dans un même diagramme.
  • Les données qui circulent : orderId → correlationId.
  • Les critères de succès de chaque étape.

Pour l'architecte

Le parcours devient visible et revu, pas seulement dessiné.

Prototype · pas une version de Microcks
07 · Ce que montre le prototype

Microcks vérifierait les appels reçus

Prototype Capture du prototype Microcks : vérification en échec du workflow placeOrderSaga ; les appels reçus ne suivent pas l'ordre attendu, l'étape reserveStock était attendue avant chargePayment.
Clic ou touche Z : capture complète

Ce qu'on voit

  • L'application a appelé les mocks Microcks.
  • Microcks compare ces appels au workflow Arazzo.
  • Verdict : échec, le paiement a été appelé avant la réservation de stock — exactement un prérequis de type dependsOn.
  • L'étape fautive, la requête et la réponse sont affichées.

Pour le QA et le dev

Un verdict qui pointe l'étape, pas un log de 3 000 lignes.

Hypothèse · à valider ensemble
08 · Si l'hypothèse tient · à vous

Un fichier, trois métiers : votre avis

workflow.arazzo.yaml dans git, revu en PR Architecte décrit le parcours Développeur code contre les mocks Testeur / QA vérifie en CI 1 · PR du workflow 2 · implémentation vérifiée 3 · régression → retour archi
  1. Quel parcours casse le plus souvent en recette ?Notre candidat pilote pour un premier fichier Arazzo.
  2. Ses contrats OpenAPI / AsyncAPI sont-ils à jour ?Sinon, c'est le vrai premier chantier.
  3. La vérification par Microcks vous servirait-elle ?Sur les mocks, sur la recette, en CI ? Ou pas du tout ?
  4. Qui serait propriétaire du workflow ?Archi, produit, QA ? Sans propriétaire, il meurt.

Merci !

DEGODEZ Sébastien · Staff Engineer · Maintainer Microcks

Annexe
Annexe · nouveau en Arazzo 1.1

L'étape événementielle

policy-events : attendre la police émiseAsyncAPI step
- stepId: attendrePoliceEmise
  operationId: $sourceDescriptions.policyEvents.onPolicyIssued
  action: receive
  dependsOn: [ payer ]
  correlationId: $steps.payer.outputs.paymentId
  timeout: 30000                  # ms
  successCriteria:
    - context: $message.payload
      condition: $.status == 'ISSUED'
      type: jsonpath
  outputs:
    policyId: $message.payload.policyId

action

send publie un message, receive en attend un, sur un canal du contrat AsyncAPI (type: asyncapi).

correlationId

Relie le message reçu à ce parcours. Doit être aligné avec celui déclaré dans le contrat AsyncAPI.

timeout · $message

Délai max d'attente en ms ; $message.payload lit le message reçu. Ici, dependsOn prend tout son sens.

Présentations