laitimes

"Backend" takes you through DDD permission platform modeling and practice

First, the background

When discussing DDD landing with many WeChat friends, he also gave some of his own insights, but rarely had the opportunity to try how to solve some real scenarios by hand, so through the DDDinAction project, he landed and improved his ideas little by little through the code practice of the permission platform.

Of course, there are many people who want to find a DDD practical project code, so after iterating some codeMaker features, they will really land infosys-auth permission platform of infosys-plat to see how to write better code in DDD.

2. Requirements for permission platforms

2.1 List of General Requirements

  1. Build a unified permission platform to connect with company-wide permission application scenarios
  2. Implement a permissions model based on RBAC
  3. Provide API interface of web management platform, support dubbo, springboot API, and provide jar package access authentication of SDK
  4. Unified management of roles, permissions, users, system menus, etc
  5. The first version implements CURD for the core business model, and partially imports and exports functions
  6. Open up the approval flow platform to realize automatic permission approval
  7. Supports the application of fine-grained data permission rules, such as a user can only access the data of a list for the last three months
  8. Temporary authorization, such as a user opening a temporary authorization for another user and withdrawing it upon expiration
  9. Permission operation logging audit component access
  10. Permission risk auditing

2.2 System Participants

role Use features illustrate
Permissions platform super administrator Permissions all features of the platform A separate table storage super administrator configuration may be required
Line-of-business administrators Configure roles and related system menu resources Configured by a super administrator
Individual access system users Permission verification and control SDK access

2.3 Business Processes

In the demo case of this project, we focus on two important business processes to look at the business timing diagram

2.3.1 Permission building process

"Backend" takes you through DDD permission platform modeling and practice

2.3.2 User authentication process

"Backend" takes you through DDD permission platform modeling and practice

Third, the permission model

3.1 Permission Context Analysis

"Backend" takes you through DDD permission platform modeling and practice

3.2 Permission Domain Model Documentation

It should be noted here that this project will not have too much modeling process, do not do too much identification of the corresponding scene, and try to ensure that an article can talk about the entire practical content, so it will directly give the modeling documents in related fields. Of course, if you have some questions about the code, you are also welcome to exchange and discuss.

"Backend" takes you through DDD permission platform modeling and practice

3.3 Entity Division

Entity name Entity description Entity behavior
AuthorityBO Permissions model Disable, enable, and determine whether a certain type of permission resource is available
DataAuthorityBO Data permissions model
SystemAuthorityBO System permissions model Build system permissions
AdminAuthorityBO Administrative authority model
UserAuthAggregateBO Aggregation model from the perspective of user permissions
RoleAuthAggregateBO Aggregation model from the perspective of role permissions
UserGroupBO User group model Determines whether the user group is associated with the specified role
RoleBO Role model Disable, enable, associate the list of users
RoleGroupBO Role group model
RoleUserBO Role user association model
SystemBO System model Add a module
ModuleBO Menu module model Add a button
MenuBO Button model

3.4 Value Object Division

Value object Value object description remark
DataColumnBO Data field model There are additions, deletions, modifications, checks, etc., but they look more like configuration class objects, and the configuration objects are collectively called value objects here
AuthorityTypeEnum Permission type Enumerated objects, in an enumeration class, are unified as value objects
UserBO User object The user object is considered a business object in the user service, but in the permission system, it only relies on this object to achieve the integrity of the model and business, and the user state is not under the authority control, so it can be regarded as a value object, but it is under the domain.support package, indicating that it is an object under the support domain.
DepartmentBO Department object Same as user objects
Address Provincial, city, and county objects This object is considered a composite object, but it is only part of the permission aggregation, and has no actual behavior and state, so it can be regarded as a value object.

It should be noted here that there is not much demonstration of the expression of value objects in this project demonstration, such as the UserID object for userId, of course, there are some big guy demo articles that will do this. In this project, the most basic data type is used to express the value object, and try not to increase the traversal and dependency depth of the object.

In the process of practice, we may not be able to pay too much attention to some rules that can be generated by value objects, rather than simply doing object encapsulation for some of the identified attributes, which will undoubtedly make the entire business object a little fragmented, and at the same time increase the difficulty of understanding the business, and practice will also be shackled with some concepts of DDD. I will have the opportunity to talk about this aspect later.

So in most cases, value objects don't actually need to use object wrapping completely, in my opinion, if you realize that this is a value object or you can divide an object or data structure is a value object. Encapsulating with basic types does not mean that we cannot express its rules and business scenarios, so it is not necessary to specify this as a value object at the domain layer, such as XXVO, but it is important to express which objects are value objects through the documentation.

3.5 Aggregate Root Identification

Aggregate root Aggregate root description polymerization
AuthorityBO Permissions, the permissions corresponding to the entire role are uniformly associated, and the internal permissions are data permissions, administrative permissions and system permissions Roles can be associated with many permission resources, which currently identify three categories, and subsequent permission resources can be customized, that is, there is also this object of resources in this aggregation, but it is not paid special attention to, which is a metaphor. So permissions are approximately equal to resources.
UserAuthAggregateBO Permission aggregation model based on user perspective Because it is an RBAC model, we cannot intuitively see what permissions the user has, then this permission is equivalent to a snapshot aggregation of the read scene, and the write is still managed through the role of permission resources
RoleAuthAggregateBO Permission aggregation model based on role perspective When reading, because there is an overall AuthorityBO for aggregate management, then this role may correspond to multiple AuthorityBOs, so you need to see how many permission resources this role has through the role dimension.
SystemBO An aggregation model based on the system menu dimension This is equivalent to a province, city and county model, the point is that this model is dynamically changing, and the permission system is more dependent on him, but the maintenance in the permission system is because this is a core permission resource, so for the permission and the system menu itself the system is an overall aggregate object, the system itself needs to shield the internal menu and buttons, the external dependence is the system and its internal menu button business indication to do reading dependence.

4. Service in the field of authority

4.1 Domain Services Documentation

This document reflects the biggest difference between using DDD and not using DDD, because building a service interface for context-oriented aggregation is equivalent to abstracting and summarizing the underlying data table and related services as a whole, so it does not seem to be the kind of table and interface and service class. Due to the special distinction between different scenarios, and the use of relying on inversion so that the application layer does not call the infrastructure layer across layers, the overall scalability can be achieved, the flexibility is high, and maintenance and modification will become easier.

"Backend" takes you through DDD permission platform modeling and practice

4.2 Area Competency Table

context Corresponding module Description of competence
User groups user Group management of a certain type of user
Role groups role Group management of a type of role
role role Maintain roles and their associated role-user associations
system system Maintain resources related to the system and its menu buttons
Data fields config Provide data permissions related to metadata information management and maintenance
Permissions authority Provide the abstraction ability of unified permission resources, and decouple roles and concrete resources
Administrative authority authority Provides configuration associations for administrative-related permission resources
Data permissions authority Provides configuration associations for data-related permission resources
System permissions authority Provides configuration associations for system-related permission resources

5. Permission Platform Cola Application Architecture

5.1 Permission Application Schema

"Backend" takes you through DDD permission platform modeling and practice

5.2 Two practices of the anti-corrosion layer model

  1. An interface method encapsulation of downstream dependent interfaces at the domain layer is an implementation of the domain gateway, such as the dependence on cache operations, the dependency encapsulation of other downstream interfaces, and the returned and requested objects are counted in the domain, but need to be distinguished from the core model in the domain.
  2. The second is the business downstream services that the entire field depends on, such as user interfaces and departmental interfaces in the user center. This kind of thing builds dependent downstream interface methods in the ACL package of the infrastructure layer, and the internal implementation calls the downstream interface logic and returns it by domain object, and the request object can be converted to DTO by the domain object BO.

The above two methods have their own advantages and disadvantages, if the domain layer is encapsulated, the application layer can directly access the downstream interface across the domain layer to some extent. If you are building at the infrastructure layer, you may need to consider the transformation of objects and the business processing of downstream methods within the domain.

5.3 CQRS mode application

In this project, the core business module is separated by reading and writing, providing two sets of interfaces for reading and writing, and at the same time, the reading is also specially separated at the domain level. At the app level, command+executor is used to handle permission-related business processes at the application level, such as granting role authorization.

5.4 CQE mode application

In the domain layer, the various data business entities under bo are specifically classified, such as BO, EVENT, MsgBody. Therefore, when the application layer controls the business application through command+executor, the Evevnt will be converted through the CMD object of the application layer. One advantage of this is that it can be done asynchronously.

The code demonstration example is as follows:

"Backend" takes you through DDD permission platform modeling and practice

What needs to be said here is that there are actually several applications of events, let's take a look:

In-domain events (events generated within the domain service)

Application-layer events (some application-layer events are also transaction-related), events with transactional characteristics, and other listening events

Messages extended by events (for example, because an event requires sending a message, or receiving a message)

Some of the above events sometimes use synchronous operations because of business characteristics, and sometimes asynchronous implementation, but it should be noted that because there are many application scenarios of events, excessive use may cause a certain degree of complexity and cannot ensure the continuity of the overall business, after all, the code is meant to be seen. A feasible way is to make a special distinction between different events, and at the same time associate the event with the event handler as much as possible to make dynamic configuration routing.

5.5 Specification Mode Application

Before using spec mode, I also reviewed Eric's book. An attempt was made in the query scenario of the system menu button in the application layer. It seems to work well, and several simple query interfaces are built in the SystemQueryFacadeIml of the application layer, and at the same time determine whether different query conditions are met through the specification mode, so that the number of external interfaces becomes very small, and the read logic of other modules can be closed. Here's a code example:

"Backend" takes you through DDD permission platform modeling and practice
"Backend" takes you through DDD permission platform modeling and practice

Internally, different query scenarios can be closed through specification routing. However, it should be noted that the application of the specification model in Eric's book is at the domain level, which is equivalent to different specifications for more complex table queries or statistical queries at the domain level. So before some friends said which layer the specification model is applied, my suggestion is that both the application layer and the infrastructure layer can be used. Of course, if it is a domain layer, if you practice according to Eric's book, the domain layer may need separate classes to build query SQL and query objects, so the DDD code you see is actually different for different practices.

5.6 Standalone Class Mode Application

Because the permission model is more complex, there will definitely be a lot of construction of the entire permission data here, so it is necessary to design the cache-related logic, so the cache prefixes of different business modules are defined in the domain layer, and the cache service classes of different business objects are built in the infrastructure layer. Since the application layer cannot reference the cache service class directly to the infrastructure layer, in order to maintain the consistency of the overall layered architecture, a CacheServiceGataWay interface is defined in the domain gateway package. Routing calls are made inside interface implementation methods through different business object identifiers.

The specific code is not screenshotted, if you are interested, you can take a look down.

5.7 Application of Occam's razor

When writing code, the code classes of different modules generated by CodeMaker are used at the beginning, but the control of aggregation in actual applications will make some generated code classes very embarrassing, such as the interface implementation under different permission types in the facadeimpl of the application layer, because the control of aggregation These different permission interfaces become relatively redundant, so it is shaved off by @Deprecated annotations, and the corresponding CURD goes to the Authority aggregation interface.

Of course, a similar situation has also appeared in the auth-adapter, so don't be surprised when you look at the code, so that the comparison is good and bad.

5.8 DDD strict layered architecture

Because the Cola architecture is adopted here, the implementation of the dubbo interface is placed in the application layer, so it seems that the domain layer and application layer that the interface implementation of springboot depends on are not very coordinated, of course, the reality is that there will not be two sets of external APIs with different styles in a project. Then I want to emphasize here that in this project, there will be no application layer across the domain layer to implement the call infrastructure layer interface.

Of course, after the auth-adapter module guarantees its responsibilities as a user interface layer, it is originally necessary to access the domain layer through the application layer, but in the project the application layer is the implementation layer of dubbo, so the auth-adapter accesses the application layer and the domain layer. Note that the application layer is accessed here because the command+executor class is used in some modules that want to be referenced. Without a dubbo implementation, the overall application layer would serve the auth-adapter separately. There will be no such special cross-layer call.

5.9 Service Dependency Description

Interconnect to the approval flow interface to implement automatic permission approval capabilities

Connect with the user center to obtain user and department data

Docking with provincial, municipal and county data services

6. Code project description

6.1 Project Home Page

To illustrate here in a unified way, my actual DDD code is basically in this project: https://gitee.com/codergit.com/dddin-action There are two engineering contents released in this iteration:

Infosys-auth platform code under the infosys-plat project

Stock-simple-demo under YoupinShop Project

6.2 Project Content

Provide basic additions, deletions, modifications, and checks for each business object

Provide a minimal middleware dependent environment, convenient for starting projects (theoretically only rely on the database), integrate cache, MQ is also more convenient, internal default to implement empty content for these, a small amount of development can achieve the full version

Provides Dubbo interface and Spring Boot interface implementation

Provide domain model documents, domain service documents, DDL documents

Add detailed annotations to the project code that handle each scenario

VII. Summary

The overall base code is supported by Tianhua-codeMaker, which can directly fill in the business method content.

Provide auth-common packages, no longer need to rely on coderman-utils, the overall dependency is closed.

Explain the theory of different scenarios, output different processing schemes to control the complexity of the project, and do code practice on the recent DDD theory learning.

There is also a lot of confusion in the process of implementation, so I also consulted some senior bosses, and at the same time built some feasible methods and ideas in the project according to my own understanding.

Article Source: https://mp.weixin.qq.com/s?__biz=MzI3MzEzMDI1OQ==&mid=2651835225&idx=1&sn=e18c2f4f21e70fdc9aaa0b941adeb448&chksm=f0dc9d25c7ab1433b9c6eb802be36998121afaed17253ba599d1d2e972a1db8ba7767044095e&scene=21#wechat_redirect