Event Bus: Inside or Outside the Hexagon?
Where does a Message/Event Bus belong in Hexagonal Architecture?
Q. In Hexagonal Architecture, where does a Message/Event Bus belong?
A. It depends! (Because of course it does.)
In Hexagonal Architecture, we can often rely on the question of: “does it do I/O to support its work or run out-of-process?” If not, then it can live inside the Hexagon, otherwise it’s on the outside (in adapters). Note that you need to include all of its dependencies when answering this question.
You want to use a library to do lightweight Domain Events publishing. The code is in a single EventBus Jar, and it doesn’t do any I/O, nor any out-of-process communication. All events are “broadcast” to listeners by calling methods defined in a Listener interface (aka the Observer Pattern) as they happen. As long as it is easy to instantiate and Test-Double the EventBus (for testability, of course!), then it can go inside the Hexagon.
You want to take advantage of Spring’s Application Event support.
In order to publish an event, you need a reference to an
ApplicationEventPublisher, which is in Spring’s context module.
This brings in the Spring Framework as a dependency, and, well, that means it cannot go inside the Hexagon.
What about JobRunr?
It’s a dedicated library for running jobs asynchronously, on a regular schedule, etc.
Usually you would use it with a real database (for persistence and potential scaling), but you can run it with an
Technically, you might be able to run it within the Hexagon, but it’s complex enough—and deals with concurrency/threads—that I’d push it outside the Hexagon.
I’d use an Outbound Port to initiate scheduling jobs, and an Inbound Adapter to handle execution of scheduled jobs.
Since a mere configuration change could cause it to depend on a real database, that would completely eliminate it from running inside the Hexagon.