Schema Registry & compatibilité des messages

Maîtriser l’évolution des schémas, la compatibilité, les formats Avro/JSON/Protobuf et garantir la stabilité d’un système Kafka distribué dans le temps.

Contexte

Dans un système distribué, les producteurs et consommateurs n’évoluent pas au même rythme. Une modification de structure (ajout de champs, suppression, changement de type) peut casser des centaines de microservices si rien n’est contrôlé.

Le Schema Registry résout ce problème en fournissant :

  • une base centralisée de schémas versionnés,
  • des règles de compatibilité,
  • un contrôle strict des messages publiés,
  • une protection contre les évolutions dangereuses.

Il devient ainsi un élément essentiel dans toute architecture Kafka professionnelle.

Lexique

Schema Registry

Service qui stocke et versionne les schémas (Avro, JSON Schema, Protobuf).

Avro

Format binaire compact très utilisé avec Kafka + support de compatibilité native.

ID de schéma

Identifiant unique de version envoyé avec chaque message.

Compatibilité backward

Les nouveaux schémas lisent les anciens messages.

Compatibilité forward

Les anciens consommateurs lisent les nouveaux messages.

Compatibilité full

Backward + Forward. La plus restrictive.

Diagramme

Schema Registry Kafka

Le producteur enregistre son schéma, obtient un ID, puis envoie les données annotées avec cet identifiant. Les consommateurs récupèrent dynamiquement le bon schéma.

Exemple de code & configuration

# Dépendances Maven Avro + Schema Registry

  io.confluent
  kafka-avro-serializer
  7.0.0



# Producteur Kafka Avro
Properties props = new Properties();
props.put("bootstrap.servers", "localhost:9092");
props.put("key.serializer", "io.confluent.kafka.serializers.KafkaAvroSerializer");
props.put("value.serializer", "io.confluent.kafka.serializers.KafkaAvroSerializer");
props.put("schema.registry.url", "http://localhost:8081");

String topic = "commandes.ecommerce";

CustomerOrder ordre = CustomerOrder.newBuilder()
    .setCommandeId(123L)
    .setClientId("clientX")
    .setMontant(250.5)
    .setStatut("CREATED")
    .build();

ProducerRecord record =
  new ProducerRecord<>(topic, "clientX", ordre);

producer.send(record);
producer.flush();
producer.close();
    

Exemple Kafka Connect – Avro + Schema Registry

{
  "name": "outbox-avro-connector",
  "config": {
    "connector.class": "io.debezium.connector.postgresql.PostgresConnector",
    "plugin.name": "pgoutput",
    "database.hostname": "localhost",
    "database.port": "5432",
    "database.user": "kafka",
    "database.password": "kafka_pw",
    "database.dbname": "ecommerce",
    "database.server.name": "dbserver1",

    "table.include.list": "public.outbox_commandes",

    "key.converter": "io.confluent.connect.avro.AvroConverter",
    "value.converter": "io.confluent.connect.avro.AvroConverter",
    "key.converter.schema.registry.url": "http://localhost:8081",
    "value.converter.schema.registry.url": "http://localhost:8081",

    "transforms": "outbox",
    "transforms.outbox.type": "io.debezium.transforms.outbox.EventRouter",
    "transforms.outbox.route.topic.replacement": "commandes_ecommerce_${eventType}"
  }
}
    
Bonnes pratiques :
  • Utiliser la compatibilité BACKWARD comme valeur par défaut.
  • Ne jamais supprimer un champ — le rendre optionnel.
  • Always add default values for new fields (Avro best practice).
  • Vérifier le schéma via CI/CD avant d’autoriser la mise en production.
  • Documenter les versions de schémas utilisées par chaque microservice.

Section avancée (réservée)

[private role= »access_kafka »]

📌 Évolutions interdites (règles internes Clean Code Craft) :

  • Interdiction totale de changer le type d’un champ existant.
  • Interdiction de rendre un champ obligatoire s’il était optionnel.
  • Interdiction de renommer un champ : toujours créer un nouveau.
  • Interdiction d’utiliser des schémas JSON bruts sans validation.

📌 Check-list de migration sécurisée

  • Créer un schéma V2 → publier dans Registry.
  • Lancer les consumers compatibles V2 en premier.
  • Activer backward compatibility strict.
  • Déployer les producers V2 en dernier.

📌 Pattern entreprise : Registry Locks & Safe Release Windows

Ce pattern permet d’empêcher la publication accidentelle d’un schéma incompatible.

[/private]

Résultat

Votre pipeline Kafka devient stable, versionné et résilient. Les producteurs et consommateurs peuvent évoluer indépendamment sans casser les flux existants.

Résumé

Le Schema Registry est un élément incontournable dans une architecture event-driven moderne. Il garantit la compatibilité des messages dans le temps, sécurise les évolutions et améliore la robustesse globale du système.

Quiz rapide

  • Quelle différence entre compatibilité backward et forward ?
  • Pourquoi Avro est-il plus fiable que JSON pour les messages Kafka ?
  • Que se passe-t-il si un consumateur reçoit un message avec un schéma inconnu ?

Exercice pratique

Objectifs :

  • Créer un schéma Avro Commande.
  • L’enregistrer dans Schema Registry.
  • Émettre un message conforme.
  • Créer une V2 avec un champ optionnel noteClient.
  • Valider backward compatibility.

Ateliers pratiques

Atelier 1 — Mise en place d’un topic Avro complet

  • Créer schéma Avro → envoyer via API Registry.
  • Configurer producteur Avro + ID de schéma.
  • Valider la désérialisation côté consumer.

Atelier 2 — Migration d’un schéma en production

  • Créer V2 avec champ optionnel + default.
  • Activer BACKWARD.
  • Faire un test de compatibilité via API REST.
  • Déployer producer V2 progressivement.

Atelier 3 — Mise en place d’un registre multi-environnements

  • Créer 3 registries : dev / staging / prod.
  • Configurer les URLs dans les microservices.
  • Implémenter un pipeline CI validant chaque schéma automatiquement.

Navigation