preface

Within each project, it has its own set of uniform development specifications. For example, the API interface must return a uniform format, the entity object must inherit the specified class, and so on. Good design can make development work twice as hard, while bad design can make development feel bad.

Without further ado, the following is the design of this project.

The specific implementation

The API uniformly returns the class ApiResult

The first thing to design is the API return format, as follows:

@Slf4j
@Getter
@Setter
public class ApiResult<T> implements Serializable {

    private static final long serialVersionUID = 2538767816320181885L;

    protected Integer code;

    protected T data;

    protected String message;

    public ApiResult(a) {}public ApiResult(Integer code) {
        this(code, null.null);
    }

    public ApiResult(Integer code, T data) {
        this(code, data, null);
    }

    public ApiResult(Integer code, T data, String message) {
        this.code = code;
        this.data = data;
        this.message = message;
    }

    public static ApiResult success(a) {
        return success(null);
    }

    public static <T> ApiResult<T> success(T data) {
        ApiResult apiResult = withCode(ResultCode.SUCCESS);
        apiResult.setData(data);
        return apiResult;
    }

    public static ApiResult fail(String message) {
        ApiResult apiResult = withCode(ResultCode.FAIL);
        apiResult.setMessage(message);
        return apiResult;
    }

    public static ApiResult withCode(ResultCode resultCode) {
        return withCode(resultCode, null);
    }

    public static <T> ApiResult<T> withCode(ResultCode resultCode, T data) {
        return newApiResult(resultCode.getCode(), data, resultCode.getMessage()); }}Copy the code

The return type of all API interfaces must be ApiResult, and the unified format is convenient for front-end processing. Use as follows:

@RestController
public class IndexController {

    @GetMapping("/index")
    public ApiResult<String> index(a) {
        return ApiResult.success("Hello World"); }}Copy the code

Return result of successful call:

{
  "code": 200."data": "Hello World"."message": "Success"
}
Copy the code

Return result of call failure:

{
  "code": 500."data": null."message": "Failure"
}
Copy the code

API returns the status code ResultCode uniformly

@Getter
@AllArgsConstructor
public enum ResultCode {

    SUCCESS(200."Success"),

    FAIL(500."Failure"),

    /* 参数错误:1000 - 1999 */

    /* User error: 2000-2999 */
    USER_NOT_LOGIN(2001."User not logged in"),

    /* The interface is abnormal: 3000-3999 */
    ;

    private Integer code;

    private String message;
}
Copy the code

The current status code is not complete and can be added while developing features, and of course it can be dynamically configurable at a later stage. But we can design the range of error types in advance:

  • The range from 1000 to 1999 indicates that the parameter is incorrect
  • The range from 2000 to 2999 indicates a user error
  • The range from 3000 to 3999 indicates that the interface is abnormal

This allows the front-end developer to roughly determine the error based on the status code.

The entity class base class Common

@Getter
@Setter
public abstract class Common {

    /** ** founder */
    private String createUser;

    /** * create time */
    private Date createDateTime;

    /** * modify */
    private String modifyUser;

    /** * Change the time */
    private Date modifyDateTime;
}
Copy the code

Common is the base class for all entity classes and is used to set Common properties for all entity classes.

Paging query

Paging query is essential in the project, the following design of paging query condition base class and paging query unified return.

Paging query Condition base class Condition

@Getter
@Setter
public abstract class Condition {

    /** * Number of entries per page */
    private int numPerPage = 20;

    /** * the current page number */
    private int pageNum = 1;

    /** * sort the fields */
    private String orderField;

    / * * * are sorted in descending order by default * /
    private String orderDirection = "desc";
}
Copy the code

Paging queries uniformly return QueryResult

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class QueryResult<T> {

    /** * total number of entries */
    private Long total;

    /** * returns the result set */
    private List<T> items;
}
Copy the code

Controller base class BaseController

public abstract class BaseController {

    /** * get the current user number */
    public String getCurrentUserCode(a) {
        / / TODO for implementation
        return null;
    }

    /** * sets the creation information */
    public void setCreateInfo(Common common) {
        common.setCreateUser(getCurrentUserCode());
        common.setCreateDateTime(new Date());
        setModifyInfo(common);
    }

    /** * Set modify information */
    public void setModifyInfo(Common common) {
        common.setModifyUser(getCurrentUserCode());
        common.setModifyDateTime(newDate()); }}Copy the code

BusinessException BusinessException

Exception design is especially important in a project. It is agreed that the exception must be BusinessException or a subclass. This facilitates unified handling of subsequent exceptions.

public class BusinessException extends RuntimeException {

    public BusinessException(String message) {
        super(message);
    }

    public BusinessException(String message, Throwable cause) {
        super(message, cause); }}Copy the code

conclusion

At this point, some basic design is complete. Different businesses may have different designs, but good designs, applicable designs are important.

The source code

Github.com/zhuqianchan…

Review past

  • Build backend frameworks from scratch – keep updating