Experimenting with Axon Framework 5, my first findings

Hi!

We’ve been experimenting with Axon Framework 5, and specifically the DCB. We’re trying to leverage the DCB to do some pretty cool stuff that would not have been possible in AF4, and I got it to work… Sort of :-). I just wanted to post my case here as feedback, and I was wondering if I have understood the framework correctly, What I missed, and what’s on the horizon.

We’re diving in a pretty Dutch domain, and it’s written in Kotlin. The case is about crossing a domain boundary (from the BRK to the WOZ) where the DCB shines I think. I have this command in which multiple plots of land get merged into one:

class UpdateWozObjectRelatieNavVereniging(
    val nieuwPerceel: KadastraalObjectId,
    val oorspronkelijkPercelen: Set<KadastraalObjectId>,
    val ingangsdatum: Ingangsdatum
) : Command()

I built a command handler where I inject a state:

@CommandHandler
fun handle(
   command: UpdateWozObjectRelatieNavSplitsing,
   @InjectEntity(idResolver = RelevantePercelenResolver::class) oorspronkelijkPerceel: State,
   eventAppender: EventAppender) { ... }

The interesting situation here is that I got a collection oorspronkelijkePercelen, which I have to unite in my command handler into 1 Perceel. What I want to do is this:

 @InjectEntity(idProperty = "oorspronkelijkePercelen") oorspronkelijkPerceel: Map<KadastraalObjectId, State>

But I can I? In any case,I did not and I built an entity resolver to resolve the state to being essentially 1 state of all the relevant plots combined. Here I again ran into the fact that I have a collection, not a determined number of items. I could not easily get an EventCriteriaBuilder that would easily allow events having 1 of the tags in a collection… I made this (of which I am not proud):

fun resolveCriteria(id: RelevantePercelen): EventCriteria {
  val tags =
    id.relevanteDingen.map { Tag.of(nl.overheid.ubb.woz.KADASTRAAL_OBJECT_ID, it.toString()) }.toSet()

  // zipWithNext levert een leeg lijstje op als er maar 1 criterium is.
  if (tags.size == 1) {
    return EventCriteria.havingTags(tags.first())
  }

  return EventCriteria.either(
    tags
      .map { tag -> EventCriteria.havingTags(tag) }
      .zipWithNext { criteria1, criteria2 -> criteria1.or(criteria2) },
  )
}

What I would like to be able to do is something like EventCriteria.any(tags). And perhaps a bit of a more fluent interface to do more complicated things with collections in EventCriteria…

The code is open source, and can be found here:

The command handler I am referring to is here: app/src/main/kotlin/nl/overheid/ubb/bridge/brk/PerceelMutatieCommandHandler.kt · main · digilab.overheid.nl / research / Uit Betrouwbare Bron / Beproevingen / WOZ Axon Kotlin · GitLab

I very much like to hear from you! What did I miss? What’s on the horizon?

Overall, it’s a lot to get used to, but as I’m getting the hang of it: I like the flexibility the DCB offers me. It does feel a bit more complicated, but I think I’m already trying to accomplish something complicated, So I think it’s fine ;-).

That’s some interesting use case you’re picking up here, @maartenjanvangool! Having a collection of entities injected with the @InjectEntity is currently not a supported feature. To be frank, I am a little hesitant to include it. We would hope users do not accidentally load all entities of a given type, for example, which would become a lot easier to accidentally do if a collection of an entity can be injected…

Nonetheless, it’s worth discussing. Would you, perhaps, be up to draft an issue for this? I think you deserve the credits for coming up with the idea, which will be set in stone if you make the issue, hence why I am asking.


We agree in those note! The event criteria construction can definitely be improved. During the construction and early usages, we just couldn’t find a one-size-fits-all approach just yet. So, we decided to “put it in the wild” for a bit and collect feedback. Like you’re doing right now, so thanks for that!

If curious, the issue we put the simplification under can be found here. Feel free to add your two cents there as a comment :pray:


Concluding, sorry for the late reply! I took a (I think) much-needed vacation right after the conference, and got back last week. Still working through all work stuff that I “collected” during my time off. :sweat_smile:

1 Like

Thanks for the response! I will draft an issue and take a look at the other.

1 Like