Skip to content

Instantly share code, notes, and snippets.

@muniter
Created March 2, 2024 13:39
Show Gist options
  • Save muniter/7c1a84b0ad104a688555e8b6825e76f6 to your computer and use it in GitHub Desktop.
Save muniter/7c1a84b0ad104a688555e8b6825e76f6 to your computer and use it in GitHub Desktop.

Hacen parte:

  • Servicio A (Productor):
  • Servicio B (Consumidor):
  • Broker:

Tiempo 1

En este tiempo son iguales los esquemas, todo bien.

# Esquema en servicio A (Productor)
class SuperEvento:
  id: int
  nombre: str
  precio: float

  def topic_name(self):
    return "super_evento"

# Esquema en servicio B (Consumidor)
class SuperEvento:
  id: int
  nombre: str
  precio: float

  def topic_name(self):
    return "super_evento"

Tiempo 2

En este tiempo se modifica el esquema en el servicio A (Productor) pero se deja igual en B (Consumidor), pues es un cambio compatible. Y pulsar los dejará seguir produciendo y consumiendo eventos.

Este cambio no require que el servicio B (Consumidor) cambie, pues a el no le interesa este nuevo dato en el evento, el uso de este campo sería para otros servicios downstream, o por el mismo deseo del equipo de A de tener más información en el evento.

# Esquema en servicio A (Productor)
class SuperEventoV1:
  id: int
  nombre: str
  precio: float
  interesado: str  # NUEVO CAMPO

  def topic_name(self):
    return "super_evento"

# Esquema en servicio B (Consumidor)
class SuperEventoV1:
  id: int
  nombre: str
  precio: float

  def topic_name(self):
    return "super_evento"

Tiempo 3

Ahora es tiempo de realizar un cambio breaking en el esquema, lo que require tener otra versión del evento que debe ser publicada por otro tópico. Lo que ocurre ahora es que el servicio A (Productor) se encarga de publicar eventos en ambas versiones (1 y 2) y el servicio B (Consumidor) en este caso no se ve afectado pues sigue con la versión 1 pues para el los datos son suficientes.

# Esquema en servicio A (Productor)
class SuperEventoV2:
  id: int
  nombre: str
  precio_cents: int  # Cambio de tipo y nombre (precio en centavos)
  interesado: str

  def topic_name(self):
    return "super_evento_v2"

class SuperEventoV1:
  id: int
  nombre: str
  precio: float
  interesado: str  # Nuevo campo

  def topic_name(self):
    return "super_evento"

  @staticmethod
  def from_v2(v2: SuperEventoV2):
    return SuperEvento(
      id=v2.id,
      nombre=v2.nombre,
      precio=v2.precio_cents / 100,
      interesado=v2.interesado
    )

# Al momento de publicar
evento_v2 = SuperEventoV2(
  id=1,
  nombre="Evento 1",
  precio_cents=1000,
  interesado="Juan"
)
evento_v1 = SuperEventoV1.from_v2(evento_v2)

# Publicar en ambos tópicos
producer.publish(contenido=evento_v2, topic=evento_v2.topic_name())
producer.publish(contenido=evento_v1, topic=evento_v1.topic_name())

Mientras el servicio B sigue con la versión 1, y no ha tenido que cambiar nada.

# Esquema en servicio B (Consumidor) sigue manteniendo la versión 1
class SuperEventoV1:
  id: int
  nombre: str
  precio: float

  def topic_name(self):
    return "super_evento"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment