In today’s distributed, microservice prevailing, most projects have adopted the microservice framework, front and back end separation mode. Off-topic: The responsibilities of the front and back end are more and more clear. Now the front end is called the big front end, and the technology stack and the ecosystem are very mature. Back end people used to look down on the front end people, but now back end people have to rethink the front end, the front end is well established.

= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =

The general architecture of the general system is as follows:



To be clear, some people will reply that this architecture is too simple, too low, there is no gateway, cache, message middleware, etc. Since this article mainly introduces the API interface, we will focus on the other module partners to supplement.

The interface interaction

The front end and the back end interact. The front end requests the URL path according to the convention and passes in relevant parameters. The back end server receives the request, processes services and returns data to the front end.

The restful style of the URL path, as well as the requirements of the common request header (such as: app_version, API_version,device, etc.) of the passed parameters, are not introduced here.

How do back-end servers return data to the front end?

Returns the format

The back end returns to the front end in JSON body mode, which is defined as follows:

{# Return status code code: INTEGER, # Return information description message:string, # return value data:object} Copy codeCopy the code

CODE status CODE

Code returns the status code, which is used to add whatever is needed during development. If the interface wants to return a user permission exception, we add a status code of 101, and the next time we add a data parameter exception, we add a status code of 102. This satisfies business as usual, but the status code is too cluttered

We should refer to the status codes returned by HTTP requests. Here are some common HTTP status codes:

200 - Request successful 301 - Resource (web page, etc.) permanently transferred to another URL 404 - Requested resource (web page, etc.) does not exist 500 - Internal server error copy codeCopy the code



We can refer to this design, and the benefit of this is to classify the error type into some interval, and if the interval is not enough, we can design it into four digits.

The value ranges from 1000 to 1999. The value ranges from 2000 to 2999. The value ranges from 3000 to 3999Copy the code

In this way, the front-end developer, after receiving the return value, can know what the error is based on the status code, and can quickly locate the error based on the description of the message related information.

Message

This field is relatively simple to understand, is the error occurs, how to friendly prompt. The general design is designed with the code status code, such as



Define the status code in the enumeration



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

Data

Returns the data body in JSON format, which varies according to the business.

We’re going to design a return body class Result



Control layer Controller

We will process the business request at the Controller layer and return it to the front end, for example the Order order



We see that after we get the Order object, we wrap the assignment with the Result constructor and then return it. Do you find that the constructor wrapper is not troublesome, we can optimize it.

Beautiful and optimization

We can add static methods to the Result class, just to make sense



So let’s change the Controller



The code is not more concise, also beautiful.

Elegant optimization

We saw above that static methods were added to the Result class, making the business processing code simpler. But have you noticed that there are several problems with this?

1. Each method returns a Result wrapper object with no business implications

2. In the business code, we call result. success on success and result.failure on exception. Is it a lot of redundancy

In fact, we can use Hibernate validate to verify whether the id is null. There is no need to make a judgment in the method body.

Our best approach is to return the real business object directly, preferably without changing the previous business approach, as shown below



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

Implementation scheme

Do you have any ideas on how to achieve it? In this process, we need to do several things

Define an annotation @responseresult to indicate that the value returned by this interface needs to be wrapped

Intercept the request and determine if it needs to be annotated at @responseresult

3. The core step is to implement ResponseBodyAdvice and @ControllerAdvice, determine whether the return value needs to be wrapped, and if so, override the return value of the Controller interface.

Annotation class

To mark the return value of a method, whether wrapping is required



The interceptor

Intercepting the request, whether the value returned by the request needs to be wrapped, is essentially parsing the @responseresult annotation at runtime



The core idea of this code is to get this request, whether you need to return the value wrapper, set an attribute tag.

Overwrite return body



The code above is to determine whether return value wrapping is required, and if so, to wrap it directly. Here we only deal with normal successful wrapping, what if the method body reports an exception? Handling exceptions is also easy, as long as you determine whether the body is an exception class.



How to do global exception processing, space reasons, old care here will not be introduced, as long as the idea is clear, on the line of their own transformation.

Rewrite the Controller



Put an @responseresult annotation on your controller class or on your method body, and you’re done. Simple. The design idea that returns to this is completed, is not concise again, elegant again.

Finally, by the way, I will send you a classic learning materials. I have packed the classic e-book libraries used in university and work (including data structure, operating system, C++/C, network classics, front-end programming classics, Java related, programmer cognition, career development), interview and job hunting materials together here.

Welcome to follow my wechat official account, scan the qr code below or long press the identification QR code, you can follow the above mentioned computer classic electronic books 100 books.

                                                

conclusion

Is there room for further optimization in this scheme? Of course there is. For example, each request needs to be reflected, whether the method to get the request needs to be wrapped, in fact, can do a cache, do not need to be resolved every time.

Source | r6d. Cn/tEvn