[Note]www.thoughtworks.com/insights/bl… This article is about software design choices. In particular, large systems may be divided into multiple deployable objects in the form of service endpoints. I won’t talk specifically about service endpoint design, but I want to discuss the idea phase of creating multiple service applications. When we are faced with complex problems, we often try to understand the individual parts of the complexity. By breaking down the problem, we break it down into parts that are easier to understand and manage. As described in many product/project management cycles, for real life problems, this is often driven by instinct. We don’t use formulas to understand what it takes to go to a country that requires a visa. We knew we needed a visa to travel, and we slowly learned the documents we needed, which forms we needed to fill out and how to fill them out. When we perform one of these steps, we don’t keep all the details of the process in mind, but just do the task at hand. This is related to the size of the task to be completed. The underlying real criteria are about time or progress, our execution, our cognitive ability and its relationship to the level of familiarity with the tasks, and maybe even the physical location where those tasks are performed (consulate vs. Photoshop, etc.). It’s not that different in software development. Over the years, the waterfall formula has been applied to software development processes, ultimately primarily based on heuristic and experience-based assessment techniques (plan poker, T-shirt sizes) and agile processes. In real life, we try not to dwell on the whole journey, but to try and understand the journey by observing our latest performance. The same applies to our problem modeling software. What we started breaking them down into different applications was the ease of managing individual applications, faster development and deployment with fewer dependencies, and ultimately more freedom of technology choice. We realized that we couldn’t have a complete process that worked for everyone. We look at the pieces and recognize our collective experience with design patterns or techniques and try to apply the best of them. An interesting software design technique for understanding and addressing complexity isDomain-driven design(DDD). Domain-driven design advocates modeling based on the business realities relevant to our use cases. Because the DDD approach is now obsolete and the level of publicity is declining, many of us have forgotten that the DDD approach really helps to understand the problem at hand and design software toward a general understanding of the solution. Issues that DDD will discuss in the form of domains and subdomains in building applications. It describes the individual steps/domains of the problem as boundary contexts, emphasizes the use of a common language to discuss these, and adds many technical concepts such asEntities, value objects, and aggregate rootsRules to support implementation. Sometimes these technical rules are seen as a hard barrier to DDD implementation, but in the end, people tend to forget that the important part is organizing code artifacts around business problems and using the same common language as (1).
Boundary context designed for service applications
The architectural style I want to talk about is very similar to microservices. It is about separating monolithic applications into multiple independent service applications, or developing them individually from the outset with the help of a bounded context (DDD concept). There are many resources that highlight the benefits of finer grained services in the microservice narrative. More and more articles, blogs, and other content are written about pitfalls and safety nets that should be in place before or during the transition to fine-grained services. I will try not to duplicate the benefits of microservices or other supporting elements that are needed to migrate to such an architecture. I don’t want to emphasize the “small” nature of the resulting services, but rather how they can be better separated by applying domain-driven design concepts. Let’s use a real life example to implement our idea – debit/credit card fetch domain. This domain can be implemented (unfortunately, it is often the case) as a set of monolithic applications. The only reason we have multiple applications is because of strict technical constraints (such as wanting to perform batch processing) in different applications.Most successful architectures I’ve seen recognize that integration through a database is a bad practice because it blurs the line between technical applications and business responsibilities, lets business logic leak into the database, and prevents horizontal scaling by adding more application servers. Therefore, the evolution to a better architecture is in the form of service integration of monolithic applications.Now, the boundaries between applications are clearer. However, as you can see, there are still hidden database interactions, this time occurring within the individual applications. I call them hidden because they’re usually hard to notice at first. Over time, entanglement of code artificially correlates previously separate business processes and introduces more friction into business development, as co-hosting requires joint deployment of separate functions, which can slow things down. If you are lucky enough to have a domain model to guide you, domain modeling can help you identify and isolate complex implementations. If you don’t already have a domain model of your existing application (as is often the case in most cases), it might be better to build the domain model and map functionality to the application at hand rather than walk through the code to understand the different responsibilities. This saves time and avoids the risk of drowning in details. Also, if there is a gap between the business and the development team, which is probably the main reason the domain model didn’t exist in the first place, discussing the domain model and mapping capabilities to existing applications will help close that gap.The next step in our design evolution is to reflect domain boundary separation into our architecture and boundary context. Having multiple boundary contexts in a domain means that more than one service application can run in the same domain. With a domain model in place, potential points of separation are more visible, allowing us to benefit from potential finer grained applications (such as the benefits of separate distribution and versioning, the potential for more feature-driven pure service endpoints, and so on, most of which are already in placeMicro serviceDiscussed in the article). While much of the microservices discussion revolves around technology agnosticism and development specifications (avoid/destroy the whole), one that is very valuable for the applications that most of us work on is the domain and design aspect. Once you move to a microservice architecture (with the help of a domain model), DDD and more fine-grained services can work together and support each other.This would also provide the team with a degree of independence, more complete service functionality, and more separation of interactions, as described in many microservices articles. Again, as you can see from our example credit card payment fetch domain, this is not the most fine-grained separation our service can achieve. Rather, it is the most meaningful separation guided by our domain knowledge. It’s not about size, it’s about business capability. I believe this is “the right SOA”, as many circles say.