DDD — Introduction to Domain Driven Design in OutSystems 11
When we talk about software architecture in OutSystems, terms such as ‘Microservices’, ‘Monolith’ and ‘Domain Driven Design’ often appear. Let’s try to understand how these terms are related and why they exist.
In a way, when we start to develop software in our factories, we need to leverage our applications so that they are available as quickly as possible and that they have a very simple and efficient communication between components. This seems very reasonable from a first point of view. This type of construction, with high dependency between components and strong connections is called ‘Monolith’.
With the growth of our applications and our factories, this type of construction and architecture begins, over time, to become painful. Why? As we have a high degree of dependency between components, even small changes lead to a loss of independence and the life cycles of different concepts are not individualized, leading to joint deployments, more complex, slower, and much more difficult maintenance to manage. How can we solve this problem? Decoupling concepts in architecture. Here is born the concept of ‘Microservices’. With Microservices, we can have different teams developing different functionalities and different concepts in the same factory without impacting other lines of development. The type of references and connections that start to be used are weak, meaning that changes that do not change service signatures or interfaces do not have to be known or renewed by consumers, thus enabling deployments only by line of business and/or life cycle of each component.
Is this the “great solution that solves everything”? No. There are several considerations to be taken into account in the process. ‘Monolith’ has their advantages and so do ‘Microservices’. Within what are its advantages and disadvantages, we must choose what suits us best.
As advantages of the ‘Monolith’:
• Process communication takes place within the same transaction. Rollback situations are handled more efficiently, and database transactions also occur in a single process.
As advantages of ‘Microservices’:
• All application developments from different lines of business or different lifecycles can be done independently without having to transport all producers/consumers.
It becomes complicated to have to choose between one solution or another, and often the best solution is somewhere in between. From here comes a ‘hybrid’ solution, called ‘Domain Driven Design’.
First question, what is a domain?
A domain is a ‘box’ that respects a set of guidelines of a line of business or life cycle, defining limits of what must be developed within that same domain in order to be independent of everything else.
And how to use them?
We must follow two fundamental rules for a domain-based architecture to work:
• Use Strong coupling within domains (the reference to the same type of development as in ‘Monolith’). This will guarantee faster and easier transactions to manage within the same concept without destroying or complicating the remaining processes in the factory;
• Using loose coupling across domains (the reference to the same type of development as in ‘Microservices’). This allows for quick and independent deployments between different lines of business and/or different life cycles, as well as simpler and more abstract management between consumers and producers (those who consume do not need to be aware of the technical complexity of the developments carried out in the producers).
How can we define the domains?
In two ways: Vertical or Horizontal. Horizontal domains are those that deal with foundation and/or generic services that will be consumed and widely used by vertical domains. Vertical domains are domains that represent a business concept with its respective independent lifecycle.
If we are careful in the way we catalogue our domains, we can achieve a very interesting balance in terms of communications between vertical domains, making them very limited and maintaining an upward flow, with a high percentage of communications flowing from horizontal domains for verticals.
With the ‘Domain Driven Design’ we managed to have a much more balanced and organic solution that takes advantage of the best of the concepts of ‘Monolith’ and ‘Microservices’.
However, embracing this approach must be well calculated to have the least possible impact on the solutions and applications that are currently bringing value to the business. Nobody wants to end up or go through a process with broken services, bugs that are complicated to resolve or a spaghetti architecture that is difficult to maintain.
All decisions must be made based on each one’s scenario and context. No model is the same as another (or very difficult) and we shouldn’t stick to too rigid rules that lead us to follow paths that aren’t suitable for our architecture (but we shouldn’t be too flexible either so as not to fall into the precipice). We must be careful in the way we choose our rules for our architectural model and adjust it to our reality. We must also be aware that architecture is a living organism and that what we implement today may have to be adjusted tomorrow. That is, we must always evaluate the trends, predicted scalability of each developed concept, separate concepts with different life cycles and choose the way in which each of these concepts communicates with each other.
In summary, the work of architecture is never finished and with each passing day new ideas and models are emerging that can help us to improve the health of our factories.