Aller au contenu
Filtrer les règles par style d’implémentation
Partie 4 · Intégration

Messagerie ​

Les events sortent d’un bounded context par des messages. Ces règles enregistrent les events avec l’état qui les a produits (outbox), les transmettent dans l’ordre, les consomment une seule fois malgré les doublons et le désordre, et survivent à une panne du broker quand il y en a un.

Dans un monolithe, elles valent aussi entre bounded contexts qui échangent des messages dans le même processus.

En pratique ​

Quand de l’argent sort d’un wallet, le titulaire reçoit une notification. Le bounded context wallets enregistre l’event dans l’outbox, dans la transaction qui comptabilise l’écriture :

ts
const booked = await this.#journal.book(entry.value);

if (!booked.ok) {
	return booked;
}

await this.#outbox.append(entry.value.pullEvents());

Un forwarder publie ensuite l’outbox dans l’ordre (MSG-03). Dans le bounded context notifications, un consumer lit le contrat publié et met la notification en file une seule fois, même quand le message arrive deux fois :

ts
export const IncomingMoneyWithdrawn = z.object({
	eventId: z.uuid(),
	type: z.literal(MONEY_WITHDRAWN),
	version: z.literal(1),
	payload: z.object({
		holderId: z.uuid(),
		amount: z.object({ minor: z.string(), currency: z.string() }),
	}),
});

export class MoneyWithdrawnConsumer {
	readonly #consumer: IntegrationConsumer;
	readonly #notifications: NotificationService;

	constructor(consumer: IntegrationConsumer, notifications: NotificationService) {
		this.#consumer = consumer;
		this.#notifications = notifications;
	}

	subscribe(): void {
		this.#consumer.on(
			MONEY_WITHDRAWN,
			'notifications.notify-withdrawal',
			(raw) => IncomingMoneyWithdrawn.parse(raw),
			(withdrawn) => this.#notifications.notifyWithdrawal(withdrawn.payload),
		);
	}
}
  • L’écriture et ses events s’enregistrent ensemble : pas d’event sans son état, pas d’état sans son event (MSG-01).
  • IntegrationConsumer reçoit le type du message, le nom du consumer, la lecture et le traitement. Il marque le message comme traité dans la transaction du traitement, et ignore un eventId déjà traité par ce consumer (MSG-04).
  • notifications est un bounded context en transaction scripts : le consumer appelle une méthode de son service (TXS-01).
  • Le consumer ne dépend que du contrat publié, et ne lit que les champs dont il a besoin (PUB-01, PUB-05).

Règles ​

Publication

CodeRègleSévéritéDétection
MSG-01L’état du modèle et ses events s’enregistrent ensemble bloquante
MSG-02Un event enregistré ne change jamais majeurefitness
MSG-03Le forwarder publie dans l’ordre et suit ce qu’il a envoyé majeure

Consommation

CodeRègleSévéritéDétection
MSG-04Le consumer ignore les doublons et suit ses messages dans la même transaction majeure
MSG-05Une opération déclenchée par un message est idempotente, par clé métier ou par état bloquante
MSG-06L’ordre des events est respecté ou toléré majeure

Pannes

CodeRègleSévéritéDétection
MSG-07La publication et la consommation survivent à une panne du broker majeure