This repository was archived by the owner on Nov 6, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 136
Add a simple implementation of an event bus using reactor #2
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
66a3069 to
d2ab4e4
Compare
β¦ available: * `./gradlew run`: Run the main entrypoint (`Starter`) without having to reference it * `./gradlew startScripts`: Creates OS specific scripts to run the project as a JVM application * More info: https://docs.gradle.org/current/userguide/application_plugin.html
* Use immutable `Set` instead of `List` as the subscribers collection while instantiating the `ReactorEventBus`: We don't need to guarantee the subscribers order (in fact, we should avoid depending on it in order to avoid creating dependencies between subscribers based on execution order)
* Rename `VideoCreated` semantics by `VideoPublished` in order to bring more domain related language to the code instead of a CRUDy language
* Rename `DomainEvent#domainEventName` to `DomainEvent#fullQualifiedEventName`. This way we are being explicit about using a FQEN naming convention (which has been also introduced in this commit: `vendor.bounded_context.subdomain.[event|command|query].version.resource.event_occured`)
* Modify the `DomainEventSubscriber#subscribedTo` method return type from `String` to `Class<EventType extends DomainEvent>`. This way we gain a robuster contract avoiding possible mistakes returning any random string instead of the actual event we want to subscribe to.
* This also has allowed us to not having to expose as public the constant with the event name and access it from the event bus implementation. That is, now we're having a really modullar implementation Open/Closed Principle compliant.
* Set the FQEN constant as private and only expose as public the `DomainEvent#fullQualifiedEventName` method. This way we ensure by the `DomainEvent` interface that all subclasses will have the needed information in order to deal with them while serializing and so on (previously we were depending on the constant which isn't declared in the interface). I've left this `DomainEvent#fullQualifiedEventName` in order to use it when we publish the events to some distributed message broker.
* Renamed the `EventBus#notify` method to `EventBus#publish`, and `DomainEventSubscriber#react` to `DomainEventSubscriber#consume`. This way we're respecting the same semantics we use while talking about Domain Events (subscribing, publishing, and consuming) without being polluted by the semantics of Java Reactor (`react`)
* Refactor the `ReactorEventBus` class in order to use `Set#forEach` method and lambda functions extracted into their own methods in order to make it easier to read
β¦ass and execute it from the main entry point * Create the `AggregateRoot` abstract class in order to deal with recorded domain events being able to pull them out afterwards * Refactor the `EventBus#publish` contract in order to receive a `List` of `DomainEvent`s instead of a single one. I've tried with the varargs approach in order to be able to publish one single event or a list of them, but it wouldn't match the actual contract of the `AggregateRoot#pullDomainEvents(): List<DomainEvent>` return type. So taking into account we would have to convert it to an `Array` (cost O(n)) just because of that, I think it make sense to just use `List` on the `EventBus` side and simplify the signatures at least for now π€
* I've go for doing the conversion between primitive types to value objects inside the Application Service. We're used to to do so in the Command/Query handler, and when we don't have a command/query bus we tend to do so in the entrypoint controller. However, I think this way we avoid some boilerplate on the different entrypoints a use case might have, and we avoid coupling our infrastructure to all the internal structure of our domain. What do you think? * Move `tv.codely.Starter` to `tv.codely.context.video.module.video.infrastructure.VideoPublisherCliController` in order to serve as entrypoint controller through CLI
Member
|
I would like to explain some of the decisions made in the pushed commits in order to ask for your opinion @rgomezcasas. Sorry for thinking I'm Cervantes π
|
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
π΅οΈββοΈ In this PR you can find:
reactorStarter