0

When an entity is changed, I want to raise an event to notify potential consumers about the state changes. My question is, should I have

  • an xxxChanged event for each attribute, or
  • a single EntityChanged event that identifies which attributes changed?

Having more specific events seems better to me, as consumers can subscribe to only the relevant changes. The problem I run into is when I have consumers that care when any of a set of attributes change. I could have it consume AttributeAChanged and AttributeBChanged, but if both A and B change I really only need the consumer to run once.

I'm not sure if this is a problem with how I'm thinking about the events, or if I need a way on the consumer side to potentially consolidate triggers.

2
  • Define "consumer". Runtime in-memory object? Same-machine service (i.e. same machine, different runtime)? Another machine in your private network? End-user over a public connection? External APIs for business-to-business reporting? ...
    – Flater
    Commented May 13, 2021 at 22:27
  • @Flater different runtimes in the same private network. Could be on the same or different VM.
    – BenV
    Commented May 15, 2021 at 19:55

2 Answers 2

2

Both options are sub-optimal.

  • In the first case, you are increasing the network traffic, which is usually pretty expensive in a microservice architecture, for many direct and indirect reasons.

  • Second option is better, but only marginally so, because you are still sending useless traffic and triggering avoidable work.

Instead, a consumers should explicitly tell which attributes it is interested in.

(The subscription API could as well consolidate different entities (or even different events), enable buffering, merge consequent updates, prioritize consumers depending on load...)

2
  • I really like how this approach keeps the the dependency details on the consumer side. It feels like a lot to implement on the publisher side though. I'm curious if there are some 3rd Party or open source packages that enable this subscription functionality.
    – BenV
    Commented May 15, 2021 at 20:05
  • @BenV How about GraphQL Subscriptions? Commented May 16, 2021 at 0:18
2

but if both A and B change I really only need the consumer to run once

If the consumer needs to run once, then the change of these two fields counts, to the consumer, as one event.

An event is defined as a reason to take action. If you only need to take action once, then by definition there was only one event.

The problem I run into is when I have consumers that care when any of a set of attributes change.

It seems like you're trying to provide solutions for all possible consumer use cases you can think of that you might want to have in the future, rather than focusing on what concrete use cases you have before you now. That's rather impossible to answer, especially by internet strangers who have no clue about your business context.

If your approach is based on what the consumer needs (i.e. the consumer dictates requirements, you don't dictate to the consumer), then you simply have to see what it is your consumer needs, and use the system that is appropriate for their needs.
If instead you are the one dictating, (i.e. you build the system the way you want, and the consumer will deal with the API you create for them), then implement it however you see fit - you are dictating the system requirements after all.

Good tip: don't try to immediately write an all-encompassing solution, unless that is concretely asked of you. A Swiss Army knife has many solutions, but each individual solution is inferior compared to a specialized tool. The Swiss Army corkscrew is not as good as a dedicated corkscrew tool. The Swiss Army knife is not as strong as a dedicated knife. And so on.

Trying to write an all-encompassing solution often comes from not wanting to have to rewrite parts of your application. But rather than being averse to change (because the possibility of change is inevitable), rather try to minimize the impact of when you do have to change something.

This is the main goal of clean coding principles. If you stick to them, even though it may cost more effort in the short run, it will greatly simplify any change you have to make in the future. And because of that, when you practice clean coding, you won't need to be change-averse anymore, and therefore don't have to tackle the all-encompassing solution.

2
  • It seems like you're trying to provide solutions for all possible consumer use cases you can think of - This is probably true. I'm also trying to keep the event publisher from knowing too much about the consumers. For example if a consumer later needs to be aware of C changing in addition to A and B, it seems like that should be a change to the consumer, not the publisher.
    – BenV
    Commented May 15, 2021 at 20:00
  • 1
    @BenV: Don't confuse "the publisher doesn't know about the consumer" with "the publisher shouldn't be changed to provide the information its consumers need". Those are two different considerations. Think of it like anonimity. Just because you tell the publisher "hey you need to add XYZ to the event data because that data is needed" doesn't mean that the publisher magically knows who its consumers are. Only try to avoid adding consumer-specific requirements, i.e. "Consumer A needs XYZ, even though no other consumers need it". That would make the publisher aware of the specific consumer.
    – Flater
    Commented May 16, 2021 at 14:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.