Skip to content

Commit

Permalink
walkthrough documentation - AxonFramework behind the boundary
Browse files Browse the repository at this point in the history
  • Loading branch information
JohT committed Dec 23, 2021
1 parent 800e2f7 commit c9ccd65
Showing 1 changed file with 37 additions and 0 deletions.
37 changes: 37 additions & 0 deletions showcase-quarkus-eventsourcing/WALKTHROUGH.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ The following topics are meant to lead you through the code and highlight most i
* [Connecting JTA Transactions to AxonFramework](#Connecting-JTA-Transactions-to-AxonFramework)
* [Connecting JSON Binding to AxonFramework](#Connecting-JSON-Binding-to-AxonFramework)
* [Mitigate Core API dependencies](#Mitigate-Core-API-dependencies)
* [AxonFramework behind the boundary](#AxonFramework-behind-the-boundary)

## Structure

Expand Down Expand Up @@ -105,6 +106,42 @@ Therefore, serialization libraries provide annotations for constructors. This in

As an example have a look at [ChangeNicknameCommand.java](./src/main/java/io/github/joht/showcase/quarkuseventsourcing/message/command/account/ChangeNicknameCommand.java).

### AxonFramework behind the boundary

Following "Entity Control Boundary" or "Ports'n'Adapters", an extreme but interesting experiment is to define interfaces between the core (domain) of the application and AxonFramework. This is not meant to be an advice to do so. It has a couple of pros and cons as listed below. But it is for sure an interesting experiment.

#### Interfaces and adapters

As an example, AxonFramework's `CommandGateway` is represented inside the application by the boundary interface [CommandEmitterService.java](./src/main/java/io/github/joht/showcase/quarkuseventsourcing/messaging/command/boundary/CommandEmitterService.java) and implemented by the [CommandEmitterAdapter.java](./src/main/java/io/github/joht/showcase/quarkuseventsourcing/messaging/command/axon/CommandEmitterAdapter.java). The adapter is created in [AxonConfiguration.java](./src/main/java/io/github/joht/showcase/quarkuseventsourcing/messaging/infrastructure/axon/AxonConfiguration.java) which also contains the CDI producer for the application.
[AccountResource.java](./src/main/java/io/github/joht/showcase/quarkuseventsourcing/service/account/AccountResource.java) uses the [CommandEmitterService.java](./src/main/java/io/github/joht/showcase/quarkuseventsourcing/messaging/command/boundary/CommandEmitterService.java) uses [CommandEmitterService.java](./src/main/java/io/github/joht/showcase/quarkuseventsourcing/messaging/command/boundary/CommandEmitterService.java) to send commands as it would be done with the `CommandGateway`.

#### Pros
* It should be easier to update to a newer version of AxonFramework, especially when there are breaking changes.
* It provides additional possibilities to extend/customize functionality provided by AxonFramework dedicated for the application.
* It defines and documents exactly those framework features that are used and hides the rest.
* The additional abstraction could be used for integration tests, that shouldn't produce side-effects via AxonFramework, e.g. by replacing those parts by mocks.

#### Cons
* It introduces additional complexity.
* It makes it harder to compare it to other applications, especially when different names are used.
* It is harder to discuss AxonFramework related topics because of the customization in between.
* Before using a new feature of the framework, the abstraction/boundary needs to be extended first.
* Axon Aggregate tests are harder to setup because they also need to be aware of the customized parts.

#### Lessons learned

Updating minor version of 4.x did not lead to changes in core domain code. But it is also very likely,
that this would also have been the case without boundary.

The extreme approach to define meta annotations even lead to [a code change](https://github.com/JohT/showcase-quarkus-eventsourcing/commit/d0d3e623f3ef8aea8b75162416372f0b44be87d0#diff-38a240ea3c3ebfc9e839fa2220fa1935d5bcc49ba1bcb58c000e9d97cda2ccb3) in
[QueryModelResetHandler.java](./src/main/java/io/github/joht/showcase/quarkuseventsourcing/messaging/query/boundary/QueryModelResetHandler.java) that wouldn't have been necessary otherwise. A transparent change inside an annotation of the framework needed also to be done on its meta annotation.

#### Summary

To summarize, it could be beneficial to applications with a big or fast growing core domain to put some effort in designing a boundary (e.g. interfaces) to frameworks like Axon, to be able to adapt future versions fast, customize the structure and even the behavior to perfectly fit the application and to have code that documents which parts of the frameworks are used.

This is by no means at no cost. It introduces additional complexity, makes it harder to move code between different applications with different boundaries and needs also to be maintained, especially when also replacing the annotations. For small Microservices it is likely to be less effort to adapt framework changes in the core domain code instead of maintaining its abstraction.

## References

* [Axon Framework CDI Support][AxonFrameworkCDI]
Expand Down

0 comments on commit c9ccd65

Please sign in to comment.