Simplify Spring Boot APIs with Graceful Response: A Quick Guide

This article introduces the Graceful Response component for Spring Boot, explaining how it provides unified response wrapping, global exception handling, and custom error codes to eliminate boilerplate, improve readability, and streamline API development with practical code examples and configuration tips.

macrozheng
macrozheng
macrozheng
Simplify Spring Boot APIs with Graceful Response: A Quick Guide

Introduction

Graceful Response is a Spring Boot component that offers a one‑stop solution for unified response wrapping, global exception handling, and custom error codes, helping developers save time, improve code quality, and make controller logic clearer.

Strongly recommended to spend 3 minutes learning it!

Project example repository: https://github.com/feiniaojin/graceful-response-example.git (choose the latest branch).

Supported Spring Boot versions: 2.x with Graceful Response 3.2.1‑boot2, and 3.x with Graceful Response 3.2.1‑boot3.

Current Problems in Spring Boot API Development

In typical Spring Boot projects, controller code often suffers from low efficiency, repetitive boilerplate, and poor readability. The following pseudo‑code illustrates the common pattern:

@Controller
public class Controller {
    @GetMapping("/query")
    @ResponseBody
    public Response query(Map<String, Object> paramMap) {
        Response res = new Response();
        try {
            // 1. Validate params
            if (illegal(paramMap)) {
                res.setCode(1);
                res.setMsg("error");
                return res;
            }
            // 2. Call service
            Object data = service.query(params);
            // 3. Set result
            res.setData(data);
            res.setCode(0);
            res.setMsg("ok");
            return res;
        } catch (Exception e) {
            // 4. Exception handling
            res.setCode(1);
            res.setMsg("error");
            return res;
        }
    }
}

The issues are:

Low efficiency : Most of the code is dedicated to wrapping results rather than business logic.

Repetitive work : Every endpoint repeats the same validation and wrapping steps.

Poor readability : Core logic is buried under redundant code.

Graceful Response can solve these problems.

Quick Start

Adding Graceful Response

Graceful Response is published to Maven Central. Add the dependency:

<dependency>
    <groupId>com.feiniaojin</groupId>
    <artifactId>graceful-response</artifactId>
    <version>{latest.version}</version>
</dependency>

Enable Graceful Response

Annotate the main application class:

@EnableGracefulResponse
@SpringBootApplication
public class ExampleApplication {
    public static void main(String[] args) {
        SpringApplication.run(ExampleApplication.class, args);
    }
}

Controller Layer

After enabling the component, controller methods can return plain objects; Graceful Response will automatically wrap them.

@Controller
public class Controller {
    @RequestMapping("/get")
    @ResponseBody
    public UserInfoView get(Long id) {
        log.info("id={}", id);
        return UserInfoView.builder().id(id).name("name" + id).build();
    }
}

The actual HTTP response becomes:

{
    "status": {"code": "0", "msg": "ok"},
    "payload": {"id": 1, "name": "name1"}
}

For command‑type endpoints that return void, Graceful Response still produces a wrapped response:

@RequestMapping("/command")
@ResponseBody
public void command() {
    // business logic
}
{
    "status": {"code": "200", "msg": "success"},
    "payload": {}
}

Service Layer

Before using Graceful Response, some developers return a custom Response object from service methods, mixing business data with status codes. With Graceful Response, service methods return plain business objects, and exceptions are mapped to status codes via @ExceptionMapper.

@ExceptionMapper(code = "1404", msg = "找不到对象")
public class NotFoundException extends RuntimeException {}
public interface QueryService {
    UserInfoView queryOne(Query query);
}
public class QueryServiceImpl implements QueryService {
    @Resource
    private UserInfoMapper mapper;
    public UserInfoView queryOne(Query query) {
        UserInfo userInfo = mapper.findOne(query.getId());
        if (Objects.isNull(userInfo)) {
            throw new NotFoundException();
        }
        // further business logic
    }
}

If NotFoundException is thrown, the response is:

{
    "status": {"code": "1404", "msg": "找不到对象"},
    "payload": {}
}

Parameter Validation

Graceful Response enhances JSR‑303 validation. By adding @ValidationStatusCode to a validation annotation, the specified error code is used when validation fails.

@Data
public class UserInfoQuery {
    @NotNull(message = "userName is null !")
    @Length(min = 6, max = 12)
    @ValidationStatusCode(code = "520")
    private String userName;
}

When validation fails, the response is:

{
    "status": {"code": "520", "msg": "userName is null !"},
    "payload": {}
}

Method‑level validation works similarly:

public class Controller {
    @RequestMapping("/validateMethodParam")
    @ResponseBody
    @ValidationStatusCode(code = "1314")
    public void validateMethodParam(@NotNull(message = "userId不能为空") Long userId,
                                   @NotNull(message = "userName不能为空") Long userName) {
        // business logic
    }
}
{
    "status": {"code": "1314", "msg": "userId不能为空"},
    "payload": {}
}

Custom Response Formats

Graceful Response provides two built‑in response styles, configurable via graceful-response.response-style:

Style 0 (default):

{
    "status": {"code": 1007, "msg": "有内鬼,终止交易"},
    "payload": {}
}

Style 1:

{
    "code": "1404",
    "msg": "not found",
    "data": {}
}

If neither format fits, users can define their own response structure.

Advanced Features

Third‑party integrations (Swagger, actuator, etc.)

Custom response bodies

Exception pass‑through

Exception aliasing

Common configuration items

Project Address

GitHub repository: https://github.com/feiniaojin/graceful-response

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.

JavaException HandlingvalidationSpring BootAPIGraceful Response
macrozheng
Written by

macrozheng

Dedicated to Java tech sharing and dissecting top open-source projects. Topics include Spring Boot, Spring Cloud, Docker, Kubernetes and more. Author’s GitHub project “mall” has 50K+ stars.

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.