Enjoy learning class guest author: Lao Gu
preface
In the mobile Internet, distributed, microservices prevailing today, now the vast majority of projects have adopted the microservice framework, the front and back end separation method, (aside: the front and back end work responsibilities are more and more clear, now the front end is called the big front end, technology stack and ecosystem have been very mature; The back end used to look down on the front end, but now the back end has to rethink the front end, which is well established).
The general architecture of the general system is as follows:
Just to be clear, some people will say,
This architecture is too simple, too low, gateway, cache, message middlewareNeither.
Because this article mainly introduces the API interface“, so we focus and other modules are supplemented by our friends.
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.
for
Restful style of the URL path, and the parameters passed in
Common header requirements (e.g. App_version, API_Version, Device, etc.), old gu here is not introduced, small partners can go to understand, is relatively simple.
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,
# the return value
data:object
}Copy 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 code returned by the HTTP request
The following are common HTTP status codes: 200 - request successful 301 - resource (web page, etc.) permanently transferred to another URL 404 - Requested resource (web page, etc.) did not exist 500 - internal server errorCopy 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 from #1000 to 1999 indicates that the parameter is incorrect
The range from 2000 to 2999 indicates a user error
#3000 to 3999 Indicates that the interface is abnormalCopy 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 encapsulated object, with no business meaning 2. In business code, we call result.success for success and result.failure for exception errors. Hibernate Validate = null; hibernate validate = null; hibernate Validate = null;
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
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 to determine if it needs to be annotated at @responseresult
- The core step is to implement the ResponseBodyAdvice and @ControllerAdvice interfaces, 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 isDetermine whether return value wrapping is requiredIf theDirect packaging is necessary. Here we only deal with normal successful packaging,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.
To 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.
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. Of course, the overall idea of understanding, partners can expand on this basis. Thanks!!
END
Welcome to long click the picture below to pay attention to the public account: Enjoy learning class online!
Public account background reply [Java], get carefully prepared architecture learning materials (video + document + architecture notes)