Where does the message bus service live in Domain Driven Design
Asked Answered
G

2

8

I am trying to further my understanding of DDD. More specifically, how to handle domain events via a message bus for asynchronous processing.

Lets say I have some architecture ->

 _____________________
|                     |
|        Client       |
|_____________________|
           |
 __________|__________
|                     |
| Application Service |
|_____________________|
           |
 __________|__________
|                     |
|        Domain       |
|_____________________|

When my domain raises some domain event, how do I get that event to a messaging service such as RabbitMQ?

My first thought is to inject a message bus service, IMessageBus, that knows how to send the events to RabbitMQ. The service would be used by domain event handlers to dispatch the event to the bus.

But then I thought, now my domain has to know how to handle its own events.

Can someone shed some light on the matter?

Guardroom answered 10/4, 2016 at 21:2 Comment(0)
P
6

The Service Bus is part of the infrastructure, however the application services know about it (as an abstraction). It's ok to inject the bus into the app service, because the app service doesn't contain domain logic but acts as the coordinator and host of a business use case.

But then I thought, now my domain has to know how to handle its own events.

Yeah, but the bus only deliver the messages, the message handlers are basically application services.

Rabbit and others are an implementation details, your app handlers should be invoked by the service bus (which should abstract the actual messaging process).

Pollute answered 10/4, 2016 at 21:32 Comment(5)
Where the abstraction of the bus lives? Does all abstractions lives in the domain, even the one only used in the application layer? I guess that it may be the case considering that you may never know when the logic will move in a domain service?Ruinous
The abstraction of the bus is part of the bus definition. The app service uses it like an external service. Important point here is that the app service it's a domain facade so not really part of the domain itself. If you define the app services inside the domain then things like repository interface are part of it, but only as a technical detail. But the bus abstraction shouldn't be part of the domain or even the app itself. After all, a service bus is an independent component that your app muses.Pollute
I'm not sure that I correctly understand your explanation. By abstractions I basically meant interfaces. Usually you would declare interfaces such as repository interfaces in the domain and implement them in the infrastructure layer. The application layer would then depend on the interface, at the exception of the composition root wich would also have to depend on the infrastructure layer. Now, this make sense because a repository interface may be used from a domain service. Therefore, should be declare the message bus interface in the domain as well?Ruinous
No. A domain service shouldn't use an external service, its job is to encapsulate specific domain behaviour (not querying for data or communicating with non-domain items). Only the app service should know/work with things like repository or service bus, even if they're just abstractions. The reason why you have an IRepository part of the domain is because you don't want other parts of the app(except persistence implementation) to have direct access to the business objects. However the bus cares only about messages which by their nature are DTOs.Pollute
I think the question "where the abstraction lives" aims at how do the entities get a reference to the bus to send the event. It's analogous to repositories. An interface like IRepository should be part of the domain layer. If it lives in the app layer, domain entities have no way to fire events nor handle them. These kinds of interfaces are cases of dependency inversion principle and plug-in pattern from Martin Fowler.Dendro
L
2

This question is analogous to "how does your domain communicate with an external system (other than for data persistence)"?

A service bus is no different from a physical sensor or other external piece of hardware. One typically represents those physical things in code as an object that abstracts the physical concept. They are outside the problem domain (PD) and can be considered System Integration (SI) objects.

If your domain needs to communicate with an external system, it simply makes a call on its equivalent SI object. Equally, an SI object can call on your domain.

Note: this answer assumes your domain is not anemic.

Leadership answered 12/4, 2016 at 6:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.