Backend API Design and Controller Standards with Unified ResultBean and AOP
The article outlines best practices for backend API design in Java, emphasizing a unified ResultBean response format, consistent interface definitions, proper handling of failure cases, avoidance of inappropriate parameters, and the use of AOP for exception handling and logging to improve code readability and maintainability.
The article discusses the necessity of a unified interface definition and controller conventions for backend development, focusing on Java Spring applications.
1. Interface Definition It lists common problems such as inconsistent return formats, neglecting failure scenarios, including unrelated or complex input parameters, and not returning appropriate data. Each issue is illustrated with erroneous code examples.
Example of inconsistent return format:
// Returning a Map reduces readability, avoid it
@PostMapping("/delete")
public Map
delete(long id, String lang) {
}
// Returning boolean on success and string on failure is a bad practice
@PostMapping("/delete")
public Object delete(long id, String lang) {
try {
boolean result = configService.delete(id, local);
return result;
} catch (Exception e) {
log.error(e);
return e.toString();
}
}Other error examples show missing failure handling, unnecessary parameters like language or userId, JSON strings as parameters, and returning only a boolean on creation.
To address these issues, the article proposes a unified response wrapper ResultBean (and PageResultBean for pagination) and provides its implementation:
@Data
public class ResultBean
implements Serializable {
private static final long serialVersionUID = 1L;
public static final int SUCCESS = 0;
public static final int FAIL = 1;
public static final int NO_PERMISSION = 2;
private String msg = "success";
private int code = SUCCESS;
private T data;
public ResultBean() {}
public ResultBean(T data) { this.data = data; }
public ResultBean(Throwable e) {
this.msg = e.toString();
this.code = FAIL;
}
}2. Controller Standards All controller methods should return the unified ResultBean / PageResultBean , avoid passing these objects further, and should not expose raw Map/JSON to service layers. Request/Response objects and direct logging should also be avoided in controllers.
The article introduces an AOP component that wraps controller execution, logs execution time, and converts exceptions into ResultBean responses:
/** Process and wrap exceptions */
public class ControllerAOP {
private static final Logger logger = LoggerFactory.getLogger(ControllerAOP.class);
public Object handlerControllerMethod(ProceedingJoinPoint pjp) {
long startTime = System.currentTimeMillis();
ResultBean
result;
try {
result = (ResultBean
) pjp.proceed();
logger.info(pjp.getSignature() + "use time:" + (System.currentTimeMillis() - startTime));
} catch (Throwable e) {
result = handlerException(pjp, e);
}
return result;
}
private ResultBean
handlerException(ProceedingJoinPoint pjp, Throwable e) {
ResultBean
result = new ResultBean();
if (e instanceof CheckException) {
result.setMsg(e.getLocalizedMessage());
result.setCode(ResultBean.FAIL);
} else if (e instanceof UnloginException) {
result.setMsg("Unlogin");
result.setCode(ResultBean.NO_LOGIN);
} else {
logger.error(pjp.getSignature() + " error ", e);
result.setMsg(e.toString());
result.setCode(ResultBean.FAIL);
}
return result;
}
}The corresponding XML configuration for the AOP aspect is also shown:
<aop:aspectj-autoproxy />
<beans:bean id="controllerAop" class="xxx.common.aop.ControllerAOP" />
<aop:config>
<aop:aspect id="myAop" ref="controllerAop">
<aop:pointcut id="target" expression="execution(public xxx.common.beans.ResultBean *(..))" />
<aop:around method="handlerControllerMethod" pointcut-ref="target" />
</aop:aspect>
</aop:config>By adopting a unified ResultBean format and AOP‑based exception handling, developers can achieve consistent API responses, simplify logging, and reduce repetitive refactoring.
Architecture Digest
Focusing on Java backend development, covering application architecture from top-tier internet companies (high availability, high performance, high stability), big data, machine learning, Java architecture, and other popular fields.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.