We as framework team have started to plan features for Axon Framework 5. Since this would be a breaking release, almost anything is possible. We would love to hear from you what you think can be improved, or new features worth considering to be part of a new major release.
Great news! The first thing that comes in mind is an API redesign of the Query API.
Currently, the query API is very difficult to “communicate”. As a client you need to know the query type, the response type and the multiplicity (response type). In the same time, there is no easy type safe way (like a Java interface) to enforce or check this, since this must be communicated over the system boundary.
I don’t have a nice solution for this, but I feel that this is a problem in every project where Axon Framework is used.
The second thing is the way how the artifacts are cut in the framework. Jan Galinski and I spoke about this with Steven and even in the Podcast. The artifacts should be usage-oriented (query client, command client, command model, query model) and not feature-oriented (es, messaging, etc).
Improve support for a local event store, Allow for Ephemeral Events: Features like that would make it possible to further differentiate events and be able to group, scope, specialize them. I can imagine that this would help to implement things like a shopping basket (like a “conversation scope”) where granular events only exists until the order is placed and are summarized into fewer or more abstract events.
Add support for Quarkus: Features like that make it easier to use AxonFramework in different environments. ( i’m biased on that one )
At the end I just want to throw in another thought: I’m not a big fan of breaking changes. For me (as a developer) this had always been the absolute last resort. Of course, if there are valuable future features that will be made possible with a thought-through breaking change and there is a migration guide, then it makes sense. I hope, that there won’t be breaking changes only because semantic versioning is seen that way
Would love to see a command response include metadata about the event(s) that were created as a result of that command, so any following queries can include those details so the query handler implementation can block until those events have been handled in the projection
This could be done now instead of waiting for Axon5, and wouldn’t be a breaking change.
@Aggregate annotation enhancement to allow a method name to be specified to use for the aggregateId as opposed to annotating a field or method. This is really a convenience thing more than a problem that needs to be solved.
Past weeks have been a bit hectic, being on vacation, came back with covid, and needing to prepare for a talk. So sorry for the late response.
Thanks a lot for all the suggestions. More are always welcome, some of them were already on our own list, it’s nice to see them validated. I’m a bit scared to make promises, but it’s almost certain we move to Java 17, and might use some a the enhancement to Java to improve the API.
There are also some nice non breaking ideas in here we might pick up later (or even earlier if time allows). As it’s open source please let us know if you would like to work on some of the things suggested. Also feel free to open a new topic if you would like to discuss some ideas in more detail.
Communicating across multiple contexts in Axon is currently unintuitive. I have struggled to find anything in the reference guide and the offered APIs are not very explicit. Since communication between multiple bounded contexts is a central concept in DDD I feel like it should be supported better.
I created two threads (Thread 1, Thread 2) on this issue and the answers helped me solve my problem. I added some thoughts on how I would imagine the API. Maybe it has some place in Axon 5. Anyways, I hope I can spark a conversation in your team on this topic.
PS: Any best practices regarding communication between contexts in Axon are more than welcome. I am still experimenting with this and I am looking for design guidelines.
Somehow related, but with another focus:
We would like to have a native option to decide if a certain event should be exposed to the outside world or should only be visible and usable within a certain module / bounded context.
From a conceptual point of view the append-only Event Store is a great idea. Unfortunately in our projects we experienced that this leads to problems for us. Sometimes it’s not feasable to extend the upcaster chain in order to evolve our events. In the context of GDPR we sometimes wish there was a solution to anonymize data in old events.
I know that “changing” the event store and therefore the history comes with its own flaws, but I just would like to share that having an append-only event store sometimes leads to cumbersome solutions and rewriting history in certain cases is much more pragmatic.
That being said we highly appreciate your work and there are a lot of ongoing improvements in the 4.x stream.
Especially the “Dead letter queue” is something that I would have requested for 5.x if it would not be planned for 4.x.
I’ve run into an issue today where an enahncement to the injection of resources into event handlers would be helpful. It would be really helpful to have the ability to inject attributes / fields from an event message into the event handler and have this taken into account when choosing which event handler to invoke. Something like the following:-
In this instance I’ve made up an @EventAttribute annotation but it could be anything that makes the most sense, possibly @PayloadAttribute or @MessageAttribute
In a similar vein to the previous suggestion, another nice feature would be the ability to inject resources into aggregates at the time of creation, instead of having to pass resources to @ComandHandler and @EventSourcingHandler methods. This would work the same as it does for sagas, e.g.
In this way, if the resource is used in multiple command / event handlers, it only needs to be injected once as opposed to on every method that requires it.
Hello @andye, I actually really like the suggestion. I do want to note that this is currently already possible! You can write this yourself and register the ParameterResolverFactory.