In today’s distributed and micro-service prevalence, most projects adopt a microservice framework and a front-end and back-end separation method. Digression: The work responsibilities of the front and back end are becoming more and more clear, and the current front end is called the big front end, and the technology stack and ecosystem are very mature; In the past, the back-end personnel looked down on the front-end personnel, but now the back-end personnel have to re-recognize the front-end, and the front-end is already very systematic.

The general overall architecture diagram of the general system is as follows:

It should be noted that some partners will reply that this architecture is too simple, too low, what gateway, cache, message middleware, no. Because Lao Gu’s article mainly introduces the API interface, we focus on other module partners to supplement themselves.

The interface interacts

with the front-end and the back-end, the front-end

requests the URL path according to the convention, and passes in the relevant parameters, and the back-end server receives the request, performs business processing, and returns data to the front-end.

For the restful style of the URL path, and the requirements of the public request header of the incoming parameters (such as: app_version, api_version, device, etc.), the old Gu will not introduce it here, and the friends can understand it by themselves, which is relatively simple.

Focus on how the back-end server implements the return of data to the front-end?


generally use the JSON body to return the backend to the frontend, which is defined as follows


{ #返回状态码 code:

#返回信息描述 message:string,



CODE status code code returns the

status code


generally friends need what they need during development, just add it.

If the interface wants to return a user permission exception, let’s add a status code of 101, and next time we want to add a data parameter exception, we will add a status code of 102. In this way, although the business can be satisfied as usual, but

the status code is too messy

We should be able to refer to the status code returned by the HTTP request, the following are the common HTTP status codes:

200 - request successful 301 - resource (web page, etc.) is permanently transferred to other URLs 404 - requested resource (web page, etc.) does not exist 500 - internal server error

We can refer to this design, which has the advantage of classifying the error type into a certain interval, and if the interval is not enough, it can be designed to 4 digits.

#1000~1999 interval indicates parameter error #2000~2999 interval represents user error

#3000~3999 interval indicates interface abnormality

In this way, after the front-end developer gets the return value, he can know what the error is according to the status code, and then describe it according to the message-related information, which can be quickly located.

The Message

field is relatively simple to understand, that is, how to give friendly prompts when an error occurs. The general design is designed together with the code status code, such as


> then defined in the enumeration , the status code

The status code and information will correspond one to one, which is easier to maintain.


returns the data body, JSON format, and different JSON bodies according to different services.

We want to design a > that returns the body class Result

Control layer controller

We will process the business request at the controller layer and return it to the front end, taking the order order as an example

We see that after getting the order object, we use the Result constructor to wrap the assignment and then return it. Have you found that the construction method such a packaging is not very troublesome, we can optimize it.

We can

add static methods to the Result class for


optimization, which can be understood at a glance

let’s revamp the Controller

Isn’t the code more concise and beautiful?

Elegant optimization

above we saw that static methods have been added to the Result class, making the business processing code concise. But have you found that there are several problems like this:

1. The return of each method is a Result encapsulated object, which has no business meaning

2. In the business code, we call Result.success when successful, and call Result.failure for abnormal errors. Is there a lot of redundancy

3, the

above code, to determine whether the id is null, in fact, we can use hibernate validation for verification, there is no need to make judgments in the method body.

Our best way is to return the real business object directly, and it is best not to change the previous business method, as shown in the figure below

This is the same as our usual code, very intuitive, directly return the order object, this is not perfect. So what’s the implementation?

In this

process, we need to do a few things

1. Define a annotation @ResponseResult, indicating that the value returned by this interface needs to be wrapped

2. Intercept the request,

Determine whether this request needs to be @ResponseResult Note

3, the

core step is to implement the interface ResponseBodyAdvice and @ControllerAdvice, determine whether it is necessary to wrap the return value, and if necessary, rewrite the return value of the Controller interface.

The annotation class

is used to mark the return value of the method and whether it needs to be wrapped


Intercept the request,

whether the value returned by this request needs to be wrapped, in fact, when it is run, the @ResponseResult is parsed and annotated

the core idea of this code , is to get this request, whether the return value is wrapped, set a property tag.

Overwrite the return body

The above code is to determine whether the return value is required to wrap, and if necessary, it is directly wrapped. Here we only deal with the normal successful packaging, what if the method reports an abnormality? Handling exceptions is also relatively simple, as long as it is determined whether body is an exception class.

How to do the overall exception handling, space reasons, Lao Gu here will not make an introduction, as long as the idea is clear, self-transformation.

Overwrite Controller

Add @ResponseResult annotations to the controller class or method body, and that’s OK, simple. The design idea returned here is complete, is it concise and elegant.

To sum up

this solution, there is no other room for optimization, of course. For example, each request should be reflected, whether the method of obtaining the request needs to be wrapped, in fact, it can be cached, and it does not need to be parsed every time.

Buy Me A Coffee