Look at the back-end API interface written, it is really called a Ba Shi~

In the mobile Internet, today when distributed and microservices are prevalent, most of the projects now adopt the microservice framework, separating the front and back ends. (Digression: The work responsibilities of the front and back ends are becoming more and more clear. Now the front end is called The big front-end, technology stack, and ecosystem are all very mature; the back-end personnel used to look down on the front-end personnel, then now the back-end personnel have to re-recognize the front-end, the front-end is already a system).

The general system architecture is as follows:

It should be noted that some friends will reply that this architecture is too simple, too low, what gateway, cache, message middleware, there are none. Because this article mainly talks about API interfaces, we focus on this point.

Interface interaction

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

Regarding 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.), we will not introduce it here. Friends can learn about it by themselves, and it is relatively simple.

How does the back-end server return data to the front-end?

Return format

The back-end returns to the front-end generally in JSON format, which is defined as follows:

{
  #返回状态码
  code:integer,
  #返回信息描述
  message:string,
  #返回值
  data:object
}

CODE status code

code returns the status code. Generally, friends add what they need during development.

If the interface wants to return a user permission exception, let's add a status code of 101, and next time we need to add a data parameter exception, add a status code of 102. Although the business can be satisfied as usual, the status code is too messy

We should be able to refer to the status code returned by the HTTP request

:下面是常见的HTTP状态码:
200 - 请求成功
301 - 资源(网页等)被永久转移到其它URL
404 - 请求的资源(网页等)不存在
500 - 内部服务器错误

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

#1000~1999 区间表示参数错误
#2000~2999 区间表示用户错误
#3000~3999 区间表示接口异常

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

Message

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

Defined in the enumeration, the status code

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

Data

The returned data body is in JSON format, and the JSON body is different according to different businesses.

We want to design a return body class Result

Controller

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

We see that after obtaining the order object, we use the Result construction method to wrap and assign, and then return. Have you found out that packaging such as the construction method is not very troublesome, we can optimize it.

Beautify

We can add static methods to the Result class, and we can understand it at a glance

Then let's transform the Controller

Is 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 the friends found several problems like this:

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

2. In the business code, we call Result.success when it succeeds, and call Result.failure for abnormal errors. A lot more

3. The above code judges whether the id is null or not. In fact, we can use validate to verify, there is no need to judge in the method body.

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

This is the same as our usual code. It is very intuitive and returns the order object directly. Isn't this perfect? What is the implementation plan?

Implementation plan

Is there a bit of thinking about how to realize it? In this process, we need to do several things

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

2. Intercept the request and determine whether the request needs to be annotated by @ResponseResult

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

Annotation class

Used to mark the return value of the method, whether it needs to be wrapped

Interceptor

Intercept the request, whether the value returned by the request needs to be wrapped, in fact, is to parse the @ResponseResult annotation at runtime

The core idea of ​​this code is to get this request, whether it needs return value wrapping, and set an attribute tag.

Rewrite the return body

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

Rewrite Controller

Add a custom annotation @ResponseResult to the controller class or method body, so that's ok, simple. The design ideas returned so far are complete, is it simple and elegant?

Is there any room for optimization of this plan? Of course there is. For example, every request needs to be reflected, whether the method of obtaining the request needs to be wrapped, in fact, it can be a cache, and it does not need to be parsed every time. Of course, if you understand the overall idea, friends can expand on this basis.

 

Guess you like

Origin blog.csdn.net/AMSRY/article/details/108683088