From Model to Code - Zoom Out

In the previous blog post, Ivan focused on translating the "music lesson booking system" event model to the source code using Axon Framework, a programming model, and Axon Server as an event store and message broker.

Final image from previous blog post. A board represents different events, commands and data views, organised and linked between them. The orange sticky notes representing the events are organised in three horizontal swimlanes, corresponding to different concepts/agregates: Account Registered is on the Account swimlane, Payment Requested, Payment Rejected and Payment Accepted are on the Payments swimlane; and Lesson Added, Lesson Request Rejected and Lesson Booked are on the Lesson swimlane. Also, the different screens and UI from the App are shown on the top and linked to the different Commands that are triggered from them.


In this part, we will zoom out and visualize how multiple software systems fit together within the bounds of an enterprise.


Systems Landscape

After the "music lesson booking system" was in production for a while, we realized that there is more than just simply adding a lesson into the system for the students to book. So we started thinking about the (sub)domain of “teacher”: Who will register teachers into the system? Who will create, draft and publish lessons so they are available to students? How are students going to pay for the classes they have booked? Let’s find out!

In the blueprint below, we now visualize three systems on the timeline: “booking”, “teacher,” and “payment”.

Now, there are some contexts identified, with red sticky notes: A Booking Context and a teacher context. Each of these contexts has its related concepts (with yellow sticky notes) that correspond to the different swimlanes. Booking context has the concepts (swimlanes): Lesson, Account and Payment. Teacher context has the following concepts/swinlanes (yellow sticky notes): Lesson and Teacher. The rest of orange sticky notes corresponding to the Events, are moved to their corresponding swimlane in the Teacher or Booking Context.

We use the second level of swimlane(s) to visualize which events (and aggregates) belong to which systems.  For example, the "TeacherRegistered" event belongs to the "Teacher" aggregate, which additionally belongs to a Teacher system. On the other hand, the payment system is not in any swimlane because we will be using a third-party system for payment processing (we are not going to implement this system).

To make this more precise, we will extract each of these systems into independent blueprints.


Booking system

The booking system remains the same. It enables students to browse and book the lessons. The only thing that is changed is who will add the lessons to this system, so they are available for booking. Creating, drafting, and publishing lessons is now the responsibility of a teacher system. The booking system will subscribe to the LessonPublished event (from the Teacher system) and publish the AddLesson command (from the Booking system).

Booking system visualization. In this board, we only show the sticky notes corresponding to the Booking System context... The events received from other Contexts (like the "Lesson published" event from the Teacher System) are also represented, but linked to the context that originates them.

This new component that translates the LessonPublished event to the AddLesson command is essentially an Event Handler in Axon. In Event Modeling, this pattern is known as the "Translation" pattern. 

Translation pattern in Axon

It is just a new adapter that we are adding, adopting the event of another system to a command of the booking system. You can still keep the old REST/UI adapter if you need this web page for some reason (in the transition process, for example).

Teacher management system

The teacher system can now independently evolve to enable managers to add teachers to the system and allow teachers to create, draft and publish lessons. 

Teacher system representation

We are not going to dive deep into this system. However, the process of translating the teacher system to the source code is very similar to the booking system we have described in the previous blog post.

We are focusing more on the strategic and integration patterns in this blog post.



Each of these systems is a subdomain model, and not all of these subdomains are equally important.

Subdomain models positioned in a diagram by Model Complexity (y-axis) and Business diferentiation (x-axis). That helps to identify the importance of the different subdomains related to the business, and to classify them into three categories: 1. Core subdomains: This are subdomains that are more important to the business than the others. These are the subdomains that you want your most experienced people working on (in the example the Booking context). 2.- Supporting sub-domains: These sub-domains are also necessary because they help perform ancilliary or, well, supporting functions related directly to what the business does (in our example, the teacher context). 3.- The Generic subdomains. Other Subdomains that facilitate the business, but are not core to it. In general, these types of systems can be purchased from a vendor or outsourced (in our example, the payment context).

We map out our domain as a portfolio of capabilities and anticipate how they may change over time. A particular focus is on identifying the core domains, the critical areas for business growth. 

In our example, we anticipate that the Teacher subdomain will transit to a supporting domain in three months. 


Bounded Contexts

The question is if these systems/subdomain models are autonomous bounded contexts.

Domain-Driven Design divides up a large system/domain model into Bounded Contexts, each of which can have a unified model - essentially a way of structuring MultipleCanonicalModels. Bounded Contexts have unrelated concepts (such as an Account aggregate only existing in a Booking context) and share concepts (such as Lesson aggregate). Different contexts may have completely different models of common concepts with mechanisms to map these common concepts for integration. 

In our case, the standard concept of Lesson is modeled as an aggregate in the booking context and as an aggregate in the teaching context. These are now two different models of the standard concept of Lesson, and each of these contexts has a unique understanding of this concept by using unified vocabulary (ubiquitous language). We have to map/translate this concept for integration between these two bounded contexts. The Event Handler component we have described earlier is acting as an anti-corruption layer (ACL) component now.


Bounded Context Mapping

Axon takes “location transparency” further than placing services behind a logical URL. In Axon, a component (for example, an Event Handler) that sends a message via CommandGateway/QueryGateway does not need to specify a destination for that message. This gives you options, as now you get to choose in which system/subdomain model to put your Event Handling component responsible for translating/integrating two bounded contexts.

Since booking is our Core domain, we would want to put the Event Handler component under the Booking context. This sets the Booking context downstream from the Teacher context. This makes the core domain model dependent on the supporting domain model and not the other way around.

This is crucial because if in the future we decided to transfer the Teacher model to a 3rd party (generic) domain model, we want to make sure that nothing is dependent on the core system. Therefore, switching a supporting system to a generic system can easily be achieved. 

The relationship between the three contexts. The Booking context has an "anticorruption layer" to communicate downstream (in a customer supplier relationship) with the Payment and Teacher contexts. Both Teacher and payment contexts offer a Open Host services /published language interface to communicate upstream with the Booking context.

The Booking context (and the team that produces it) is downstream to Teacher and Payment bounded contexts. The Event Handler component acts as an anti-corruption layer (ACL) component by not letting events from the Teacher or Payment system leak deep into the Booking domain model. 

There is a "customer-supplier" relationship between teams. The Downstream team is considered to be the customer. Downstream requirements factor into upstream planning. Therefore, the Downstream team gains some influence over the priorities and tasks of the Upstream team.

Axon Server (Enterprise) explicitly supports bounded contexts by allowing different (groups of) applications to connect to other contexts within the Axon Server. Unless specifically indicated otherwise, contexts are strictly separated, and information/messages are not shared between them.



We hope that these few blogs have given you the basic architectural ideas and tools to help you design your systems. Of course, there are many ways of doing this process. But one crucial thing to keep in mind is why a system should be chosen as core and downstream to other systems. That is where the business problem has to be identified and examined closely. Our model to code example is just one way of showing you how these tools can be helpful, and hopefully, you can benefit from these examples in your projects. 

Written by:
Sara Torrey

Sara Torrey

Sara Torrey is a Developer at AxonIQ. She is a self-taught full-stack developer, who has worked with various programming languages and frameworks, namely Java, Axon, and Spring Boot. She comes from a rather unusual background; she studied Music in university and graduate school.

Ivan Dugalic

Ivan Dugalic

Solutions architect with significant experience in designing full stack application components and providing guidance to the solutions teams in development and implementation.

Skilled in a wide variety of technology stacks and learning quickly new technologies as needed. Experience covers all facets of design patterns, software architecture, continuous delivery, agile methodologies and best practices in constructing solutions that remain scalable, adaptable and replicable. Strong engineering professional with the Master of Science (MSc) focused on Computer Science from the University of Belgrade, Faculty of Mathematics.