The interface of the Java code specification returns a unified format (enumeration class)

The general system structure is as follows:

image

What needs to be explained is that some small partners will reply that this architecture is too simple and too low. There are no gateways, caches, or message middleware. Because this article mainly talks about the API interface, 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 data to the front-end.

For the restful style of the URL path, and the requirements of the public request headers of the incoming parameters (such as: app_version, api_version, device, etc.), I will not introduce them here. Friends can learn by themselves, and it is relatively simple.

How does the backend server return data to the frontend?

return format

The backend returns to the frontend. We generally use the JSON body, which is defined as follows:

 

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

CODE status code

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

If the interface wants to return a user permission exception, let’s add a status code of 101. Next time we need to add a data parameter exception, we will add a status code of 102. Although this can satisfy the business 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 - 内部服务器错误

image.gif

We can refer to such a design, which has the advantage of classifying the error types into a certain range. If the range is not enough, it can be designed as 4 digits.

 

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

In this way, after getting the return value, the front-end developer can know the approximate error according to the status code, and then quickly locate it according to the information related to the message.

Message

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

image.png

Then define in the enumeration, the status code

image

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

Data

Return the data body in JSON format, and different JSON bodies according to different businesses.

We want to design a return body class Result

image

Control layer Controller

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

image.png

We see that after obtaining the order object, we use the Result constructor to wrap and assign values, and then return. Friends, have you noticed that the packaging of the construction method is not very troublesome, we can optimize it.

Beautification

We can add static methods to the Result class to understand at a glance

image.png

Then let's transform the Controller

 

image.png

Is the code simpler and more beautiful?

elegant optimization

Above we saw that a static method has been added to the Result class, which makes the business processing code more concise. But friends, have you noticed that there are several problems:

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 when there is an exception. Is it redundant?

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

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

image

This is the same as our usual code, it is very intuitive, and it returns the order object directly, isn't it perfect? What is the implementation plan?

Implementation plan

Friends, do you have some ideas on how to achieve it? In this process, we need to do a few things

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

2. Intercept the request and judge whether the request needs to be annotated with @ResponseResult

3. The core step is to implement the interfaces ResponseBodyAdvice and @ControllerAdvice, determine whether the return value needs to be packaged, 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

image

interceptor

Intercept the request, whether the value returned by this request needs to be packaged, in fact, it is to parse the @ResponseResult annotation when running

image

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

rewrite return body

image

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

image

Rewrite Controller

image

 

Add a custom annotation @ResponseResult on the controller class or method body, so it's ok, easy. The design idea returned here is completed, is it simple and elegant?

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

 

Guess you like

Origin blog.csdn.net/qq_41916378/article/details/109571578