18 | Example of DDD-based microservice design

In order to better understand the design process of DDD, this article will use a project to take you to understand the strategic design and tactical design of DDD, go through the whole process from domain modeling to microservice design, and master the main design process of DDD together and key points.

Basic information of the project

The goal of the project is to realize online leave and attendance management. The function description is as follows:

  1. The person asking for leave fills in the leave application form and submits it for approval. It is verified according to the identity of the person asking for leave, the type of leave and the number of days of leave. According to the approval rules, it is submitted to the superior for approval step by step.
  2. According to the attendance rules, after the leave data is written off, the attendance data is verified and the attendance statistics are output.

strategic design

Strategic design is the process of finding domain objects and aggregate roots based on user journey analysis, clustering entities and value objects to form aggregates, dividing bounded contexts, and establishing domain models.

The method used in strategic design is event storm, including several main processes such as product vision, scenario analysis, domain modeling and microservice splitting.

Suggested participants in the strategic design phase: domain experts, business demanders, product managers, architects, project managers, development managers, and test managers.

1. Product Vision

The product vision is to design the top-level value of the product, reach an agreement on the target users of the product, core value, differentiated competition points and other information, and avoid the product from deviating from the direction. During the event storm, all participants wrote their opinions on stickers for each point and posted them on the whiteboard. The host of the event storm will discuss each sticker and converge and unify the divergent opinions to form the following product vision map.

We compiled this product vision map into a paragraph: in order to meet the needs of internal and external personnel, their online leave, automatic attendance statistics and external personnel management, we build this online leave attendance system, which is an online leave platform that can automatically Attendance statistics. It can support internal and external networks to ask for leave at the same time, and manage internal and external personnel to ask for leave and regular attendance analysis, unlike the HR system, which only manages internal personnel and can only be used on the intranet. Our products can be used on both internal and external networks, enabling no-difference management of internal and external personnel.

Through product vision analysis, the project team unified the system name - online leave attendance system, clarified the project goals and key functions, key differences with competing products (HR), and its own advantages and core competitiveness.

Product vision analysis is very valuable for start-up systems to clarify the focus of system construction, unify team building goals and establish a common language. But if your system goals and requirements are very clear, this step can be ignored.

2. Scenario analysis

Scenario analysis is to explore typical scenarios in the business domain from the perspective of users, and generate the classification of scenarios that need to be supported in the domain, use case operations, and dependencies between different sub-domains to support domain modeling.

Together, project team members use event storming to analyze the user journey for leave and attendance. According to the journey and scenario analysis of different roles, sort out all operations, commands, domain events, and external dependencies from front-end operations to back-end business logic as comprehensively as possible.

Below I will take the two scenarios of asking for leave and personnel as examples.

The first scene: leave

User: leave person

  • Leave-asking person login system: Obtain leave-seeking person information and permission data from the authority micro-service, and complete login authentication.
  • Create a leave form: Open the leave page, select the leave type and start time, and enter the leave information. Save and create a leave request form, and submit the leave request for approval.
  • Modify the leave form: query the leave form, open the leave page, modify the leave form, and submit the leave for approval.
  • Submit for approval: Obtain the approval rules, obtain the approvers from the personnel organization relationship according to the approval rules, and assign the approvers to the leave form.

Second Scenario: Approval

User: Approver

  • Approver login system: Obtain approver information and authority data from authority microservices to complete login authentication.
  • Get leave request form: Get the leave request form under the name of the approver, select the leave request form.
  • Approval: Fill in the approval comments.
  • Level-by-level approval: If approval by superiors is still required, according to the approval rules, the approver is obtained from the personnel organization relationship, and the approver is assigned to the leave form. Repeat the above 4 steps.
  • The last approver completes the approval.

After the approval is completed, an event in the Leave Approval field is generated. There are two further business operations in the follow-up: sending a notification that the leave application has been approved, and the notification email system notifies the person asking for leave; sending the leave application data to attendance for verification.

 

The figure below is the analysis result of the personnel organization relationship scene, and the detailed analysis process and the scene analysis of attendance will not be described.

 

3. Domain Modeling

Domain modeling is to establish a domain model by analyzing business and problem domains. Guide the microservice boundary design upward through the bounded context, and guide the entity object design downward through aggregation.

Domain modeling is a convergent process, divided into three steps:

  • The first step is to find domain objects such as domain entities and value objects;
  • The second step is to find out the aggregate root, and establish an aggregate according to the dependency relationship between the entity, the value object and the aggregate root;
  • The third step is to define a bounded context based on factors such as business and semantic boundaries.

Let's explain it in detail step by step.

Step 1: Identify domain objects such as entities and value objects

Based on scenario analysis, analyze and find out the entities and value objects that initiate or generate these commands or domain events, and gather commands and events related to entities or value objects into entities. The figure below is the relationship between the analyzed entity and the command. Through analysis, we found entities and value objects such as leave request form, approval opinion, approval rules, personnel, organizational relationship, credit card details, attendance details, and attendance statistics. 

Step 2: Define Aggregation

Before defining an aggregate, first find the aggregate root. From the above entity, we can find two aggregate roots of "leave form" and "personnel". Then find out which entities and value objects are closely dependent on the aggregate root. We found that approval opinions, approval rules and leave forms are closely related, and organizational relations are closely related to personnel.

After finding out the relationship between these entities, we found that there are credit card details, attendance details and attendance statistics. These entities have no aggregate root. You will often encounter this kind of situation in domain modeling, and we need to deal with it in a special way for this kind of scenario.

The entities of credit card details, attendance details, and attendance statistics are independent of each other, and no aggregate root can be found. They are not rich domain models, but they complete the attendance business logic together, and have high business cohesion. We put these several business-related entities into one attendance aggregation. When designing microservices, we still use the DDD design and analysis method. Since there is no aggregate root to manage entities within an aggregate, we can use traditional methods to manage entities.

After analysis, we established three aggregations of leave, personnel organization relationship and attendance. Among them, the leave aggregation has value objects such as leave form, approval opinion entity and approval rule. The personnel-organization relationship aggregates entities such as personnel and organization relationships. Attendance aggregation has entities such as credit card details, attendance details, and attendance statistics. 

Step 3: Define Bounded Context

Since the aggregation of personnel-organization relations and the aggregation of leave requests jointly complete the business function of requesting leave, the two are within the bounded context of requesting leave. Attendance aggregation alone constitutes the bounded context of attendance statistics. Therefore, we divide the business into two bounded contexts for leave and attendance statistics, and establish two domain models for leave and attendance.

4. Splitting of microservices

Theoretically, a bounded context can be designed as a microservice, but a variety of external factors need to be considered comprehensively, such as: singleness of responsibility, separation of sensitive and stable services, non-functional requirements (such as elastic scaling, version release frequency and security requirements), software package size, team communication efficiency and technical heterogeneity and other non-business factors.

In this project, we divide microservices mainly considering the principle of single responsibility. Therefore, according to the bounded context, it can be split into two microservices: leave and attendance. Among them, the leave microservice includes two aggregations of personnel organization relationship and leave, and the attendance microservice includes attendance aggregation.

At this point, strategic design is over. Through strategic design, we established a domain model and divided the boundaries of microservices. The next step is tactical design, which is microservice design. Let's take leave microservice as an example to explain its design process.

tactical design

Tactical design is the process of designing microservices according to the domain model. This stage mainly sorts out the domain objects in the microservice, sorts out the relationship between domain objects, determines their positions in the code model and layered architecture, establishes the mapping relationship between the domain model and the microservice model, and the dependencies between services .

Suggested participants in the tactical design phase: domain experts, product managers, architects, project managers, development managers, and test managers.

Tactical design includes the following two phases: analyzing microservice domain objects and designing microservice code structure.

1. Analyze microservice domain objects

The domain model has many domain objects, but these objects have relatively heavy business attributes. To complete the transition from domain model to microservice, further analysis and design are needed. Based on the event storm, we further refine the domain objects and their relationships, and supplement the business and technical details that the event storm may miss.

What services should we analyze in microservices? Layering of services? What services are composed and orchestrated by application services? What entities and entity methods does domain service include? Which entity is the aggregate root? What properties and methods does an entity have? Which objects should be designed as value objects etc. 

Service identification and design

The commands of event storms are some external operations and business behaviors, and they are also the capabilities provided by microservices. It often corresponds to application services or domain services of microservices. We can use commands as a starting point for service identification and design. Specific steps are as follows:

  • Design application services according to commands, determine the functions of application services, service collection, composition and orchestration methods. The services in the service collection include domain services or application services of other microservices.
  • Design and define domain services according to application service functional requirements. Note here: application services may be composed of multiple aggregated domain services.
  • According to the function of the domain service, determine the entities and functions in the domain service.
  • Design entity basic properties and methods.

In addition, we also need to consider the asynchronous processing of domain events.

I take the action of submitting for approval as an example to illustrate the identification and design of services.

The general process for submitting for approval is:

  • According to the leave type and duration, query the leave approval rules to obtain the role of the next approver.
  • Query the next approver from the person-organization relationship according to the approval role.
  • Assign an approver to the leave form, and save the approval rules to the leave form.
  • Through analysis, we need to design the following services and methods in the application layer and domain layer.

Application layer: Submit the application service for approval.

Domain layer: Domain services include querying approval rules, modifying leave process information services, and querying approver services according to approval rules, which are respectively located in the aggregation of leave and personnel organization relationships. The leave form entity has a method for modifying the leave process information, and the approval rule value object has a method for querying the approval rules. The person entity has a method to query the approver according to the approval rule. The figure below shows the services we analyzed and the dependencies between them.

That's it for the service identification and design process, let's design the objects in the aggregate again.

objects in the aggregate

In the leave request aggregation, the aggregate root is the leave request. After multi-level review of the leave form, multiple approval opinions will be generated. For the convenience of query, we can design the approval opinions as entities. After the leave application is approved, the domain event of leave application approval will be generated, so there will also be a leave application event entity. The leave aggregation has the following entities: approval comments (recording approvers, approval status and approval comments) and leave event entities.

Let's analyze the value object of the leave form aggregation. The data of the person asking for leave and the next approver comes from the personnel entity in the personnel organization relationship aggregation, which can be designed as a value object. Personnel type, leave type and approval status are enumerated value types, which can be designed as value objects. After determining the leave approval rules, the approval rules can also be used as the value object of the leave form. The leave request aggregation will contain the following value objects: leave requester, personnel type, leave type, next approver, approval status and approval rule.

To sum up, we can draw the leave aggregation object relationship diagram. 

In the aggregation of personnel-organizational relationships, we can establish organizational relationships among personnel, and find superior approval leaders through organizational relationship types. Its aggregate root is personnel, and entities have organizational relationships (including organizational relationship types and superior approval leaders), among which organizational relationship types (such as project managers, division chiefs, general managers, etc.) are value objects. The superior approval leader comes from the aggregate root of personnel, which can be designed as a value object. The aggregation of personnel-organization relationship will contain the following value objects: organization relationship type, superior approval leader.

To sum up, we can draw the personnel organization relationship aggregation object relationship diagram again. 

Object manifest inside microservice

After determining the attributes of each domain object, we can design the code object of each domain object in the code model (including the package name, class name and method name of the code object), and establish a one-to-one mapping relationship between the domain object and the code object. According to this mapping relationship, relevant personnel can quickly locate the code location where the business logic is located. After the above analysis, we can analyze the object list in the microservice as shown in the figure below. 

2. Design microservice code structure

According to the code model of DDD and the packages, classes, and methods of objects in each domain, we can define the code structure of the leave microservice and design the code objects.

Application layer code structure

The application layer includes: application services, DTOs, and codes related to event publishing. Implement application services related to aggregation in the LeaveApplicationService class, and encapsulate application services for external microservice authentication and permissions in LoginApplicationService.

Here is a reminder: If the application service logic is complex, an application service can build a class, which can prevent the code of a class from being too large, which is not conducive to maintenance. 

Domain layer code structure

The domain layer includes one or more aggregated entity classes, event entity classes, domain services, factories, and warehouse-related codes. An aggregation corresponds to an aggregation code directory, and the aggregations are completely isolated in code, and the aggregations are coordinated through the application layer.

The leave microservice domain layer contains two aggregations of leave and personnel. The staff and leave codes are placed in code packages in the directory structure of their respective aggregates. If as the business develops, personnel-related functions need to be separated from the leave microservice, we only need to slightly modify the personnel aggregation code package, deploy it independently, and quickly release it as a personnel microservice. At this point, the domain objects, layers and dependencies in microservices are sorted out clearly. The overall architecture and code model of microservices are basically completed.

follow-up work

1. Detailed design

After completing the domain model and microservice design, we also need to design the microservice in detail. The following contents are mainly designed: entity attributes, database tables and fields, mapping between entities and database tables, service parameter specification and function realization, etc.

2. Code development and testing

Developers only need to find the code location corresponding to the business function according to the detailed design documents and functional requirements, and complete the code development. After the code development is completed, developers need to write unit test cases, and complete service testing based on the baffle simulation dependent objects.

Summarize

Today we have gone through the DDD design process through the online leave and attendance project.

DDD strategic design starts with event storms, and then we need to find domain objects such as entities, find aggregate roots to build aggregates, divide bounded contexts, and build domain models.

Tactical design begins with the command of the event storm, identifies and designs services, establishes the dependencies of services at each layer, designs entities and value objects in microservices, finds out all domain objects in microservices, and establishes the relationship between domain objects and code objects. Mapping relations.

In this way, the project team can be well guided in the development and testing of microservices.

Guess you like

Origin blog.csdn.net/zgz15515397650/article/details/132130089