1. Source code download address

Source: https://github.com/samt007/xygerp-api-demo

This is a set of EBS based API service system based on Spring Cloud micro-service architecture

If you have any questions about this article, please contact me at [email protected]

2. The Introduction is introduced

This is a technical document about the effective combination of traditional ERP system and Java-based microservices architecture.

Traditional ERP focuses on the internal information management of enterprises. When the ERP system can publish its services (combined with the micro-service architecture), it can achieve a seamless connection with the third party system, and also can realize the extension of ERP itself. The goal is to make ERP more open!

2.1 What is it used for?

To put it simply:

It is equivalent to an intermediate Service platform, making ERP API into Web Service and integrating with other systems.

The following details what it does.

1. Without it…

If there is no unified API docking platform, ERP and third-party system will be connected, which will be the structure as shown below:

As can be seen from the figure above, the connection between each third-party system and ERP, whether DBLINK or its own Web Service, is chaotic and cannot be managed uniformly. To put it simply, they are separate, and the things that need to be done to connect are piecemeal.

When there are more and more third-party systems, it will be a disaster for day-to-day operations. For example, in a simple operation: password change, there will be a lot of adjustments, and it is easy to miss.

In particular, the reuse of interface functionality is a challenge. Assume an inventory query interface that both the CRM system and the online ordering system can use and needs to be developed twice.

2. Since I had it…

With this unified API system, the connection between ERP system and other systems becomes this structure:

Therefore, with it, equivalent to ERP API can be developed through this service platform, basically all the business interface can be completed, can be completed through this service platform.

Can be achieved:

  • Unification of external services
  • API services can call each other, and realize the unification of service fetch and processing logic
  • Unified code, improve development efficiency. In particular, the comm code.
  • Improve the stability of interworking with third-party systems: Just pay attention to the stability of the microservice system.

3. What are the examples?

Here’s an example:

1) Barcode management system for import and export of finished products:

About this requirement: when finished products are put into storage, they can be directly put into storage by scanning bar code or two-dimensional code with bar code gun; When selling out of the warehouse, you can also brush the barcode of the finished product directly out of the warehouse. JIT management.

The implementation logic of this system is that the user name and password of EBS can be used to log into the APP system on the bar code gun. Then, when the barcode is swiped, the corresponding transaction can be generated through the Web Service! Such as the completion of warehousing, material handling orders, etc.

Here are some screenshots of the system

Note: The background API of this function is provided by the micro service, and the foreground is an Android APP

2) Integration with various third-party systems:

Every enterprise has a variety of third-party systems that need to be more or less integrated with EBS. The traditional integration method is through DBLINK.

However, with this set of Web Service system, it can be unified through the Web Service as an intermediary, and EBS data integration interaction!

2.2 What are microservices?

There is a lot of information on the Internet about its interpretation. Here refer to a great god (reference: http://blog.51cto.com/ityouknow/1974080), the end of the parse more in place:

The concept of Microservices originated in an article “Microservices” written by Martin Fowler in March 2014.

Microservices architecture is an architectural pattern that advocates the partitioning of a single application into a set of small services that coordinate with each other to provide ultimate value to users. Each service runs in its own separate process and communicates with each other using a lightweight communication mechanism (usually RESTful apis based on HTTP). Each service is built around a specific business and can be independently deployed to a production environment, class production environment, and so on. In addition, the unified and centralized service management mechanism should be avoided as far as possible. For a specific service, appropriate language and tools should be selected to build it according to the business context.

Microservices is an architectural style in which a large complex software application consists of one or more microservices. Each microservice in the system can be deployed independently, and each microservice is loosely coupled. Each microservice is only focused on completing one task and doing it well. In all cases, each task represents a small business capability.

Advantages of microservices architecture

Controllable complexity: The application is decomposed while avoiding the endless accumulation of complexity. Each microservice focuses on a single function and clearly expresses service boundaries through well-defined interfaces. Due to its small size and low complexity, each microservice can be fully controlled by a small development team, making it easy to maintain high maintainability and development efficiency.

Independent deployment: Because microservices have independent running processes, each microservice can also be deployed independently. There is no need to compile and deploy the entire application when a microservice changes. Applications made up of microservices have a series of parallel distribution processes, making distribution more efficient, reducing the risk to the production environment, and ultimately shortening the application delivery time.

Flexible technology selection: Under the microservice architecture, technology selection is decentralized. Each team is free to choose the most appropriate technology stack based on its own service needs and industry development status. Because each microservice is relatively simple, the risk of upgrading the technology stack is low, and even a complete refactoring of a microservice is feasible.

Fault tolerance: When a component fails, in the traditional single-process architecture, the failure is likely to spread throughout the process, resulting in application-wide unavailability. In a microservice architecture, faults are isolated within a single service. If well designed, other services can achieve fault tolerance at the application level through retry, smooth degradation and other mechanisms.

Scale-out: Monolithic applications can also achieve scale-out by copying the entire application to different nodes. Microservices architectures are flexible when different components of an application have different scaling requirements, because each service can scale independently based on actual needs.

2.3 ERP API microservice system architecture description

2.3.1 System development logic description

From the above analysis, microservices are a technical architecture that separates a large service architecture into several sub-services. So the question is, how do you break it up? What are the principles of service unbundling.

This question is like how to partition a large table, in fact I think it is a case by case. Since I developed a microservice system based on EBS, normally, a more reasonable division rule should be divided by MODULES of EBS.

Each module is divided into a separate microservice. For example, FND module, INV module, WIP module and so on.

Sometimes, some functions may be customized for a purpose, requiring the extraction of data from several modules, with a low probability of reuse by other modules. So, microservices can actually be divided into customized functions as well.

Currently, the system includes two sub-services:

  • Xygerp – ALD service: ALD module

This is the core ALD module of the entire microservices API. The main function of this module is to verify user login and provide unified token authentication for all API modules. Equivalent to THE FND module of EBS.

  • Xygerp – ALBC service: ALBC submodule

This project is one of the API modules of microservices: barcode management system provides data and data processing API. It is mainly used for barcode transmission system.

Of course, several services could be added in the future. The advantage of microservices architecture is the ability to scale horizontally!

2.3.2 Microservice system architecture diagram

The architecture diagram of the system is shown below.

Note:

1. In the Spring Cloud module, Actually Spring Security is not a single module, but integrated into every business micro-service module! Every microservice must have token authentication to allow access to the API, which is very important! So I listed it in the Spring Cloud module.

2. Some of the modules in the figure are not currently implemented. The architecture as a whole is currently implemented, including the following services (the purpose of each module will be specified in the next section) :

xygerp-ald

xygerp-albc

xygerp-server-eureka

xygerp-server-zuul

Note: Additional modules will be added later as needed.

3 system development process

The next step is to develop a Spring Cloud-based microservice system.

3.1 Basic development technology knowledge points that must be mastered

The foundation must be laid for any development system. Therefore, here is a list of development techniques needed to develop Spring Cloud-based microservice systems.

I won’t go into the details of how each development technique is learned, because that’s not the focus of this article. To do good work must first sharpen its tools, the foundation must be laid.

1) Java language

You have to be familiar with Java, otherwise you don’t have to look at documentation. Lay the foundation first!

2) Maven project management tool

System development projects are based on Maven project management, so you must first install and master Maven tools.

3) Oracle Database +PLSQL+SQL language

Development technology of database side. Oracle database is selected here, because EBS is an ERP system based on Oracle database.

3.2 Java frameworks you need to be familiar with

At this point in Java technology, there are many excellent open source frameworks that can be used to develop systems quickly.

3.2.1 Spring Framework Technology Stack (FamilyBucket)

Spring is currently the mainstream open source technology package. The main technology stacks used in this system are: Spring Boot, Spring Security and Spring Cloud.

  1. Spring Boot

The system is developed quickly based on SpringBoot. Choose the current hot SpringBoot, minimize the configuration complexity, put a lot of energy into business development.

  1. Spring MVC

Handle all URL requests using the Spring MVC framework, easy to use.

  1. Spring Security

Spring Security is a powerful and highly customizable authentication and access control framework. It is the standard for ensuring Spring-based applications. The Token mechanism is primarily handled here with the Spring Security framework.

  1. Spring Cloud

Spring Cloud is an ordered collection of frameworks. It takes advantage of the development convenience of Spring Boot to subtly simplify the development of distributed system infrastructure, such as service discovery registry, configuration center, message bus, load balancing, circuit breakers, data monitoring, etc., which can be started and deployed with one click using Spring Boot’s development style. Note: This system currently uses two modules of Spring Cloud

  • Requests are unified through the API Gateway (Zuul) to access internal services.
  • Upon receiving the request, the gateway retrieves the available services from the registry center (Eureka)

3.2.2 MyBatis

ORM framework selected MyBatis.

The main consideration is that it supports SQL statements well: MyBatis is an excellent persistence layer framework that supports normal SQL queries, stored procedures, and advanced mappings. In addition, also used MyBatis some plug-ins to improve the efficiency of development, especially general Mapper and PageHelper paging plug-in!

3.2.3 Alibaba druid

DRUID is a database connection pool implementation on Alibaba’s open source platform. It combines the advantages of DB pools such as C3P0, DBCP, and PROXOOL with log monitoring to monitor DB pool connections and SQL execution.

3.2.4 Swagger

The only link between the front end and the back end becomes the API interface.

API documentation is becoming more and more important as a link between front-end and back-end developers, and Swagger is a framework that lets you write API documentation better.

3.3 Software Tools to Be Obtained

3.3.1 Redis

Currently, the primary role of Redis is to access tokens in conjunction with the implementation of Spring Security to complete the API access Security mechanism.

Consider advanced features like caching or message queuing in the future.

3.3.2 rainfall distribution on 10-12 Docker

Docker-based containerized deployment.

With the microservices architecture, our system will be made up of many subsystems. In order to achieve environmental isolation between multiple systems, we can deploy them on multiple servers, but this can be expensive and the performance of each server may not be fully utilized.

So we naturally thought of virtual machines, running multiple virtual machines on the same server to achieve isolation of the environment, each virtual machine running independent services.

However, the cost of virtual machine isolation is still high because it requires more hardware and software resources from the server. Therefore, in the microservice structure, Docker is the best choice to realize the isolation of service environment. It is more lightweight than a virtual machine, consumes less resources, and enables rapid deployment.

Note: there is a section on how to install and use this tool. For reasons of space, this document does not cover containerized deployment.

3.3.3 Jenkins

Jenkins Automated build tools.

When we adopt the microservices architecture, we see a problem like this. The entire system is made up of many, many services that need to run in a separate container, so the complexity of each release can be very high.

Figure out the dependencies between these services and the order in which they start, and then compile, package, and publish the subsystems one by one. These operations are technically difficult but error-prone.

So what tools can help us solve these problems? The answer is Jenkins.

It is an automated building tool, which simply means that we just need to press a button on its interface to achieve a series of complex processes.

Note: there is a section on how to install and use this tool. For reasons of length, this document does not cover automated builds.

3.4 Specific development process

Let’s start building a system like this hand in hand.

3.4.1 Creating an organizational structure for the Maven project

Start by creating a microservice system parent project: xygerp-API

Create the following subprojects under this project:

The project name instructions
xygerp-ald Ald module, port: 8180. This is the core ALD module of the entire microservices API. The main function of this module is to verify user login and provide unified token authentication for all API modules. Equivalent to THE FND module of EBS.
xygerp-albc Albc submodule, port: 8181. This project is one of the API modules of microservices: barcode management system provides data and data processing API. It is mainly used for barcode transmission system.
xygerp-comm Comm module this project is the core dependency of all API projects. Basically, the common code for all projects of the API microservices architecture can be extracted here.
xygerp-basic-support This project is the basic data support project for all API projects. This is a unified collection of all entities! For Entity, it should be common to the entire microservice.
xygerp-server-eureka Spring Cloud’s service center for services and discovery. Port: 8101. This module is the core of Spring Cloud and handles service invocations between microservices.
xygerp-server-zuul Spring Cloud Service Gateway. Port: 8102. Zuul provides unified access to all microservices in the Spring Cloud architecture. All requests that need to communicate with the services in the microservices architecture go through the unified gateway.

Their contents turned out to look something like this:

Note: About XYgerP-basic-support: Core base support module

You may be wondering: Why not merge entity in the module it belongs to? In fact, I was mainly concerned with the issue of services calling each other.

Although microservices are objectively a separate service, in fact, most of the functions must be called each other. For example, is it normal for the sales order module to call the inventory module to query the inventory?

If entity is not shared, it is equivalent to the result of the inventory module obtained by the sales module cannot be collected into the bean for processing, which will bring great inconvenience to the background processing!

3.4.2 Building Module Dependencies

You then need to specify the dependencies between them through the POM file, as shown below.

1. Business Services:

Change to WAR deployment

Xygerp-comm and xygerP-basic-support only provide basic code support for each microservice, so jar deployment is ok.

In addition, to simplify the configuration of individual modules, we put common dependencies for all modules in the Project POM file, and then made all modules submodules of Project. This way the module can inherit all of its dependencies from the parent module without having to configure them itself.

In the parent POM, the stator module

The modules tag specifies who the child of the current module is, but it’s not enough to specify the stator in the parent module’s POM file. You also need to specify the parent in the child module’s POM file.

<modules> <module>xygerp-comm</module> <! -- Core Comm module --> <module>xygerp-basic-support</module> <! <module> Xygerp-server-eureka </module> <! Eureka --> <module>xygerp-server-zuul</module> <! -- Zuul dynamic Routing module --> <module>xygerp-ald</module> <! -- Core ALD module --> <module> xygerp-alBC </module> <! -- Submodule: ALBC module, providing bar code docking API service --> </modules>Copy the code

You need to specify the parent module in the child module

<parent> <artifactId>xygerp</artifactId> <groupId>com.xygerp</groupId> <version>1.0-SNAPSHOT</version> <relativePath>.. /pom.xml</relativePath> </parent>Copy the code

Note: specific code directly look at the source code. This is just to mention a few key Settings.

So, at this point, the module’s dependencies are configured! But pay attention to the order in which modules are packaged.

Since all modules rely on xygerP-Comm module and XYgerP-Basic-support module, it is necessary to compile, package and install xygerP-Comm module and XYgerP-Basic-support module first, and package them into the local repository. So that the upper module can reference it. After the module is installed, build the upper-layer module. Otherwise, the class library in xygerP-Comm module cannot be found when building the upper-layer module.

If you use MVN package in the parent directory, the order of the package build is specified directly in the parent POM.

2. Service governance part of microservice architecture

Xygerp-server-eureka: Spring Cloud service registration and discovery. Is to deal with governance between services.

Xygerp-server-zuul: Unified API gateway service for Spring Cloud.

Tips: These two projects are the core services used to implement the microservices architecture. So, they’re relatively independent. There is no need to rely on the parent POM.

3.4.3 Package code with MVN compilation commands

After the above projects are set up, add the dependencies that all projects need to use (refer to my source code for specific codes).

When all is well, you can use the MVN command to package the project:

mvn clean install -Dmaven.test.skip=true -P dev

Here’s a quick breakdown of the instructions:

MVN: Unified command for Maven.

Clean Install: Indicates that the project is to be built.

-dmaven.test. skip=true: indicates that the test module should be skipped during construction.

-p dev: enables the Spring boot parameter of dev to run the system during construction.

If all is well, the normal result is as follows:

3.5 Local computer test system

With the code out of the way, the next thing to think about should be how to test. After all, all systems must be tested, especially one with multiple configurations and a wide range of applications.

This brings us to the advantages of Spring Boot. The Tomcat service is built into Spring Boot’s packaged application by default. In other words, you can start a Tomcat service just by executing the Java command with the target result packaged by Spring Boot. It’s really easy to test!

3.5.1 Starting the Local System Service

Suppose my xygerp-API project is here: D:\JSP_MyEclipse\xygerp-api

Then open four CMD command Windows respectively and execute:

D: \ \ xygerp JSP_MyEclipse \ xygerp - API - server - eureka \ target > Java jar xygerp - server - eureka - 1.0 - the SNAPSHOT. War D: \ \ xygerp JSP_MyEclipse \ xygerp - API - server - zuul \ target > Java jar xygerp - server - zuul - 1.0 - the SNAPSHOT. War D: \ \ xygerp JSP_MyEclipse \ xygerp - API - ald \ target > Java jar xygerp - ald - 1.0 - the SNAPSHOT. War D: \ \ xygerp JSP_MyEclipse \ xygerp - API - albc \ target > Java jar xygerp - albc - 1.0 - the SNAPSHOT. WarCopy the code

The diagram below:

3.5.2 Local test API service system

The services of the local test environment are started, followed by specific data testing.

First test Eureka’s service registration and discovery to confirm whether the service has been registered in the system:

Then, with a swagger test the functionality of the user login: http://127.0.0.1:8102/xygerp/ald/swagger-ui.html token at present is to test whether can be normal.

The login is successful and the token for this access is generated.

Note down the tokens and test them. Continue to test the function of a query: http://127.0.0.1:8102/xygerp/albc/swagger-ui.html

Note that the Spring Security framework is used here, and all API request headers must carry token information. Otherwise the request returns 401.

If the test is OK, the system is basically set up successfully. The next step is how to deploy it in a test or formal environment, and how to build the project with one click.

In brief, docker tool is used for system deployment, Jenkins tool is used for one-click deployment project. The use of these two tools will be described in a section below.

3.6 Functional difficulties of the API microservice system implementation

3.6.1 Solve the problem of environment variables of database Session, especially the language environment and user environment.

Regarding this problem, the method I am using may not be the optimal one. If there is a better solution from other stations, please leave a message to me. Thank you very much!

Source:

Those who are familiar with EBS development should know that after logging in to ERP, every time we open the Form, the system will apply for a new database Session. At this time, the EBS system will automatically initialize the environment variables of the Session, such as the basic language environment, user environment, business entity and so on.

In this case, we can use functions like fnd_global.user_id directly in the package to obtain information about environment variables.

In Java Web development, however, things are different!

In the Java concept of accessing a database, Session application is an expensive action! As a result, most Java software that connects to databases (such as DRUID) introduces the concept of a database connection pool. Simple: Session sharing!

A concurrent problem arises when A Session is shared: user A uses the system and initializes the environment variable of this Session as user A; When user A does not use the system, the Session is idle and put back into the connection pool to be used by other users.

At this time, if user B is likely to use the Session, if the environment variable is not re-initialized, then user B will use the environment variable of the system Session as user A, which will lead to data bugs! How to deal with this problem is a difficult problem to develop the system.

Problem solving:

My current approach is to use AOP in the Service layer to automatically monitor the Service layer parameter AuthUser user

As long as you put the AuthUser user parameter last in the Service layer, AOP automatically initializes the Session environment variable. (Note that my system’s database Transaction is enabled in the Service layer!)

In addition, locale variables, login ID environment variables, and so on, are automatically initialized. Because AuthUser will carry that definition!

The core processing code is as follows:

private static final String SQL_GLOBAL_INIT
	    = " DECLARE "
		+ "    L_session_id NUMBER;L_user_id NUMBER;L_login_id NUMBER;L_LANG VARCHAR2(10); "
		+ " BEGIN "
		+ " L_user_id:=:P_USER_ID; L_login_id:=:P_LOGIN_ID; L_LANG:=:P_LANG;"
		+ " APPS.fnd_global.INITIALIZE("
		+ " session_id=>L_session_id, user_id =>L_user_id, resp_id =>NULL, "
		+ " resp_appl_id=>NULL, security_group_id=>NULL, site_id=>NULL, login_id =>L_login_id, "
		+ " conc_login_id=>NULL, prog_appl_id=>NULL, conc_program_id=>NULL, conc_request_id=>NULL, "
		+ " conc_priority_request=>NULL"
		+ "); "
		+ " IF NVL(L_LANG,'US') <> USERENV('LANG') THEN "
		+ " IF L_LANG='ZHS' THEN "
		+ " APPS.fnd_global.set_nls_context(p_nls_language => 'SIMPLIFIED CHINESE'); "
		+ " ELSE "
		+ " APPS.fnd_global.set_nls_context(p_nls_language => 'AMERICAN'); "
		+ " END IF;"
		+ " END IF;"
		+ " END; "; /*** * the service layer automatically initializes the environment variables before calling * Note that the required parameters of the user variables are placed last! * AOP automatically initializes Session environment variables as long as the AuthUser user parameter is placed last in the Service layer. * @throws Exception */ @SuppressWarnings("static-access")
	@Before("execution(* com.jebms.*.service.. *. * (..) ) && args(.. ,user)")  
    public void oracleDBInit(JoinPoint joinPoint,AuthUser user) throws Exception{
		Long dbLoginId=devDao.getJdbcTemplate().queryForObject("SELECT FND_GLOBAL.LOGIN_ID FROM DUAL", Long.class);
if(user.getLoginId()! =null&&user.getLoginId()>0&&! user.getLoginId().equals(dbLoginId)){ Map<String,Object>inParamMap=new HashMap<String,Object>();
	    	inParamMap.put("P_USER_ID", user.getUserId());
	    	inParamMap.put("P_LOGIN_ID", user.getLoginId());
	    	inParamMap.put("P_LANG", user.getLanguage());
			devDao.getDevJdbcTemplate().execute(this.SQL_GLOBAL_INIT, inParamMap); }}Copy the code

Source code at: com.jebms.comm.utils. AopUtil

3.6.2 Solving EBS User Login Problems: Use the EBS system account and password to log in to the API system.

Problem Description:

Since this is a third-party API system, username and password information is not really something the API system needs to manage.

In other words, the API system cannot verify the user name and password by following the normal process: enter the user name and password, the system verifies the user name and password of the background database, and returns the verification result.

Instead, enter the user name and password. The system invokes the ERP user name and password authentication package for verification and returns the result. Simply put: You need to add logic for custom validation.

Fortunately, the Spring Security framework supports flexible validation logic.

Adding steps:

First, write a custom authentication class: MyAuthenticationProvider

Next, add this custom validation to the definition of the Spring Security framework.

AbstractWebSecurityConfig

private MyAuthenticationProvider provider; / / custom validation auth. AuthenticationProvider (provider);

That is, it can achieve this effect perfectly

Core code:

/** * User-defined Authentication mode */ @override public Authentication authenticate(Authentication Authentication) throws AuthenticationException { String username = authentication.getName(); String password = (String) authentication.getCredentials(); AuthUser user = (AuthUser) userService.loadUserByUsername(username); System.out.println("username:"+username+",password:"+password);
        if(user == null){
            throw new BadCredentialsException("Username not found."); } // The encryption process is represented hereif(! sysService.xygErpValidateLogin(username, password)) { throw new BadCredentialsException("Wrong password.");
        }
        
        user.setPassword(passwordEncoder.encode(password));

        Collection<? extends GrantedAuthority> authorities = user.getAuthorities();
        return new UsernamePasswordAuthenticationToken(user, password, authorities);
    }

Copy the code

3.6.3 Unified development style.

1. Entity base class encapsulation.

It encapsulates the 5WHO field and forms like FND_SET_WHO methods, making it easy to develop.

In addition, in order to prevent the loss of updates, data consistency is actually detected before each update, and corresponding actions are encapsulated.

2. Encapsulation of query logic.

Query function is still relatively many, for complex query conditions how to transfer the value is a difficult problem.

This encapsulates a SearchInfo accumulation, so you can put all the query criteria in this class, and then define the matching field in the Controller layer of Java, and the system can automatically generate the corresponding and criteria.

Such as:

   @GetMapping(value = "/getPageLocator")
    @ApiOperation(value = "Paged list interface")
    public ResultEntity<PageInfo<EslipLocatorRE>> getPageLocator(
    		@ApiParam(value = "Inventory organization ID",required = true) @RequestParam(required = true) int organizationId,
    		@ApiParam(value = "Library code",required = true) @RequestParam(required = true) String subinventoryCode,
    		@ApiParam(value = "Location code",required = false) @RequestParam(required = false) String locatorCode,
    		SearchInfo searchInfo) throws Exception {
    	searchInfo.getConditionMap().put("organizationId", organizationId);
    	searchInfo.getConditionMap().put("subinventoryCode", subinventoryCode);
    	searchInfo.getConditionMap().put("locatorCode", locatorCode);
    	searchInfo.setAuthUser(this.authUser);
    	searchInfo.initSqlCondition();
    	searchInfo.andSqlCondition("MIL.ORGANIZATION_ID"."organizationId");
    	searchInfo.andSqlCondition("MIL.SUBINVENTORY_CODE"."subinventoryCode");
    	searchInfo.andSqlCondition("MIL.SEGMENT1"."locatorCode");
        return eslipService.selectForPageLocator(searchInfo);
    }

Copy the code

3. Unified packaging of processing results.

Basically any processing will either succeed or fail (warning is also a failure).

This encapsulates a result-returning base class ResultEntity<T> that can provide effective application – or Java-side interaction.

@ApiModelProperty(value = "Status code,0 means success and other means failure.", example = "0",position = 1)
private String code;
Copy the code

In particular, the front-end retrieves or processes data using the return of the resulting base class.

In simple terms, data processing success/failure, there is a unified return result identification. Note that this identifier is different from the request’s response result identifier (200)!

The request response identifier merely indicates that the Web server is responding properly, but the specific processing result may be a processing failure.

Here is a concrete example (and the interface processing that will actually be developed will look like this) :

{
	"code": "0"."message": ""."description": ""."obj": [{
		"createdBy": 1,"creationDate": "The 2017-10-10 09:37:03"."lastUpdatedBy": 10,
		"lastUpdateDate": "2017-11-16 14:47:48"."lastUpdateLogin": 96,
		"valueUUID": null,
		"id": 2."applId": 1,
		"respCode": "BASIC_SET"."menuId": 2."startDate": "The 2017-10-10 09:37:03"."endDate": null,
		"respName": "System Setup Responsibilities"."description": "System Setup Responsibilities"."menuCode": "SYSTEM_SET"."menuName": "System Settings Menu"."enabled": true}]."param1": null,
	"param2": null,
	"param3": null,
	"param4": null,
	"param5": null,
	"ok": true
}

Copy the code

The document reference links: https://juejin.cn/post/6844903560010792968 http://blog.51cto.com/ityouknow/1974080