Best Practices for API Design and Controller Standards in Java Backend Development

The article explains why a unified response format like ResultBean is essential for Java backend APIs, outlines common interface design mistakes, provides concrete coding guidelines for controllers, and demonstrates how to use AOP for exception handling and logging, all illustrated with practical code examples.

Top Architect
Top Architect
Top Architect
Best Practices for API Design and Controller Standards in Java Backend Development

In backend development, defining clear and consistent interfaces is crucial; the author highlights frequent problems such as inconsistent return formats, ignoring failure scenarios, including irrelevant parameters, and using complex input types like raw JSON strings.

To address these issues, the article recommends that every controller method return a unified ResultBean (or PageResultBean) object, avoid passing this wrapper to service layers, and convert request parameters to well‑defined beans within the controller.

Key controller guidelines include:

All methods must return ResultBean / PageResultBean to enable AOP processing.

Do not expose ResultBean beyond the controller layer.

Convert raw JSON, maps, or request/response objects to domain‑specific beans before invoking services.

Avoid logging inside controllers; let services handle logging.

Example of a problematic method returning a raw map:

@PostMapping("/delete")
public Map<String, Object> delete(long id, String lang) {
    // ...
}

Corrected version using ResultBean:

@PostMapping("/delete")
public ResultBean<Void> delete(long id, String lang) {
    try {
        boolean result = configService.delete(id, lang);
        return ResultBean.success(result);
    } catch (Exception e) {
        return new ResultBean<>(e);
    }
}

The article also provides the full definition of ResultBean with Lombok annotations, constants for success, failure, no‑login, and no‑permission, and constructors for various scenarios.

To automate response handling and exception wrapping, an AOP aspect ControllerAOP is introduced. It measures execution time, logs successful calls, and catches all throwables, converting them into a standardized ResultBean with appropriate error codes.

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 Spring XML configuration enables aop:aspectj-autoproxy, declares the aspect bean, and defines a pointcut that matches any public method returning ResultBean.

<aop:aspectj-autoproxy/>
<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 enforcing a unified response format and leveraging AOP, developers can improve code readability, reduce repetitive error‑handling code, and simplify automated testing and logging across the entire backend service.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

javaaopspring
Top Architect
Written by

Top Architect

Top Architect focuses on sharing practical architecture knowledge, covering enterprise, system, website, large‑scale distributed, and high‑availability architectures, plus architecture adjustments using internet technologies. We welcome idea‑driven, sharing‑oriented architects to exchange and learn together.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.