ddd-ts-kit/events-consumer-idempotent
Identifiant d'architecture : events/consumer-idempotent. Sévérité par défaut : error dans recommended, error dans strict.
S'applique à : chaque fichier d'un contexte, tests exclus ; le subscribe direct seulement dans application/ et dans le fichier de module.
Pourquoi
Section intitulée « Pourquoi »La livraison se fait au moins une fois. Un consommateur sans nom stable ni magasin des événements traités traite une seconde fois un événement livré à nouveau : la facture est émise deux fois. Le nom est la portée d'idempotence, il est donc écrit une fois et jamais dérivé.
<builder>.on(definition)ou<builder>.on(definition, {})suivi de.handledBy(...)ou de.handledByFactory(...), sansconsumer(une chaîne vide compte comme absente)on(definition, handler)de@ddd-ts-kit/eventsdont le troisième argument ne porte pas à la foisconsumeretprocessed- dans
application/et le fichier de module : un.subscribe(...)direct dont le gestionnaire n'est pas enveloppé paridempotent(...) - dans un projet de style déclaré (
stack.style: "declared") : une classe qui porte@IntegrationEventHandler(...)de@ddd-ts-kit/kernel/declarationsdont les options n'écrivent pasconsumercomme un littéral de chaîne non vide (absent, vide, une variable, un gabarit avec une substitution, des options contenues dans une variable ou seulement étalées)
Incorrect :
builder.on(productListedV1).handledBy(ProductListedHandler, [CommandBus]);
subscribeAll(platform.subscriber, [on(productListedV1, (event) => consumer.handle(event))]);
resolve(IntegrationEventSubscriber).subscribe('catalog.product.listed', (event) => consumer.handle(event));
// style déclaré@IntegrationEventHandler(productListedV1, { consumer: consumerName })export class CatalogProductListedHandler { constructor(private readonly commandBus: CommandBus) {}}Correct :
builder.on(productListedV1, { consumer: 'billing.price-list' }).handledBy(ProductListedHandler, [CommandBus]);
subscribeAll(platform.subscriber, [ on(productListedV1, (event) => consumer.handle(event), { consumer: 'billing.price-list', processed: platform.persistence.processedEvents }),]);
// style déclaré@IntegrationEventHandler(productListedV1, { consumer: 'billing.catalog-product-listed' })export class CatalogProductListedHandler { constructor(private readonly commandBus: CommandBus) {}}on est reconnu par son import depuis @ddd-ts-kit/events, sous n'importe quel nom local ; builder.on par la chaîne qui se termine par un gestionnaire, ce qui le distingue du on d'un émetteur d'événements. consume exige les deux options par son type et n'est pas jugé. subscribe(type, idempotent(name, store, handler)) est accepté : idempotent du noyau est ce sur quoi on et consume sont construits.
Dans un projet de style déclaré, une classe de gestionnaire d'événement d'intégration est son propre enregistrement : @IntegrationEventHandler(definition, { consumer: '<context>.<reaction>' }, [ports]) satisfait la règle et rien n'a à être écrit dans un fichier de module. Le décorateur compte quand son nom est importé de @ddd-ts-kit/kernel/declarations dans le fichier, sous un alias ou un espace de noms aussi. Un fichier de module conservé dans un projet de style déclaré est jugé comme dans le style explicite. Dans un projet de style explicite, le décorateur n'est pas lu.
Aucune.
rules."events/consumer-idempotent" à off dans ddd-ts-kit.config.json désactive la règle, et // ddd-ts-kit-disable-next-line events/consumer-idempotent -- <reason> désactive une ligne, exactement comme pour ddd-ts-kit check.
- Des options contenues dans une variable ou étalées depuis un autre objet ne sont pas suivies : rien n'est signalé comme manquant.
- Que le nom du consommateur soit unique et stable dans le temps n'est pas vérifié ici : ESLint juge un fichier à la fois, et deux
@IntegrationEventHandler, ou un décorateur et un enregistrement de module, vivent dans deux fichiers.ddd-ts-kit checkcompare les noms de tout le projet, décorateurs compris, etcreateApplicationrefuse un nom déclaré deux fois pour le même événement. - Qu'un fichier
*.integration-handler.tsporte bien@IntegrationEventHandlerest l'affaire dedeclarations-role-declared, qui signale aussi leconsumernon écrit. - Que le magasin soit transactionnel, ou que la marque soit validée avec le gestionnaire, n'est pas vérifié : préférez
consume, ou passezunitOfWork. - Tout
.subscribe(...)dansapplication/ou dans le fichier de module est pris pour un abonnement à des événements, quel que soit le récepteur.
Avec le checker de la CLI
Section intitulée « Avec le checker de la CLI »ddd-ts-kit check signale le même identifiant à partir du texte des fichiers et reste le garde-fou rapide pendant l'écriture. Cette règle fait autorité.