A lightweight, opinionated Spring-based library for standardized API responses and exception handling.
This library is designed with a focus on minimal dependencies, clean error handling, and null-free responses through the use of an EmptyResponse object.
This library was built based on the following principles:
-
π« Null-Free Design
API responses should never returnnull. Instead, a singletonEmptyResponseobject ensures empty payloads are always predictable. -
π Minimal Dependencies
No third-party dependencies beyond Spring Web and Jakarta Validation β lightweight and integration-friendly. -
π Consistent Structure
All success and error responses follow a unified format (ApiResponse<T>,ErrorResponse), making it easier to parse and document. -
π§° Developer-Centric Utilities
Includes utilities likeApiResponseUtil,ObjectsUtil, and fluent builders to reduce boilerplate code. -
π§© Easy to Customize
ExtendGlobalExceptionHandlerorAbstractGlobalExceptionHandlerand plug it into your project via@RestControllerAdvice.
Gradle
dependencies {
implementation group: 'io.github.hyeonjaez', name: 'spring-api-common', version: '0.0.1'
}dependencies {
implementation 'io.github.hyeonjaez:spring-api-common:0.0.1'
}Maven
<dependency>
<groupId>io.github.hyeonjaez</groupId>
<artifactId>spring-api-common</artifactId>
<version>0.0.1</version>
</dependency>- Unified success response wrapper (
ApiResponse<T>) - Standardized error handling with
ErrorResponse - Predefined error codes in
CommonErrorCode - Domain-specific
BusinessExceptionandErrorCodeabstraction - Extendable global exception handlers
- Singleton
EmptyResponsefor null-free design ObjectsUtilfor null/ID validationGraphQL Global Exception Handlingvia a DataFetcherExceptionResolver implementation that produces consistent error payloads in errors.extensions
com.github.hyeonjaez.springcommon
β
βββ exception # Error codes & business exceptions
β βββ BusinessException.java
β βββ ErrorCode.java
β βββ CommonErrorCode.java
β
βββ graphql # GraphQL integration
β βββ AbstractGraphQLExceptionResolver.java
β βββ GraphQLExceptionResolver.java
βββ handler # Global exception handlers
β βββ GlobalExceptionHandler.java
β βββ AbstractGlobalExceptionHandler.java
β βββ ErrorResponse.java
β
βββ response # API response wrappers
β βββ ApiResponse.java
β βββ ApiResponseUtil.java
β βββ ApiStatus.java
β βββ EmptyResponse.java
β
βββ util # Validation utility
βββ ObjectsUtil.java
@RestControllerAdvice
public class MyExceptionHandler extends AbstractGlobalExceptionHandler {
// Override default handlers as needed
}@GetMapping("/users/{id}")
public ResponseEntity<ApiResponse<UserDto>> getUser(@PathVariable Long id) {
UserDto user = userService.findById(id);
return ApiResponseUtil.ok("User fetched successfully", user);
}{
"status": "SUCCESS",
"message": "User fetched successfully",
"data": {
"id": 1,
"name": "Jaehyun",
"email": "jaehyun@example.com"
}
}public enum UserErrorCode implements ErrorCode {
USER_NOT_FOUND(HttpStatus.NOT_FOUND, "USER-001", "User not found");
}if (user == null) {
throw new BusinessException(UserErrorCode.USER_NOT_FOUND);
}{
"status": "FAILURE",
"statusCode": 404,
"errorCode": "USER-001",
"message": "User not found"
}Any BusinessException or common framework exception thrown in a @QueryMapping or @MutationMapping will be converted into a GraphQL error with standardized extensions.
@QueryMapping
public UserDto getUserById(@Argument Long id) {
UserDto user = userService.findById(id);
if (user == null) {
throw new BusinessException(UserErrorCode.USER_NOT_FOUND);
}
return user;
}{
"errors": [
{
"message": "User not found",
"extensions": {
"status": "FAILURE",
"statusCode": 404,
"errorCode": "USER-001"
}
}
],
"data": {
"getUserById": null
}
}Errors are always returned with HTTP 200, and clients should inspect errors[*].extensions.errorCode or statusCode to handle failures.
- All classes are unit-tested (e.g.,
ApiResponseTest,ErrorResponseTest, etc.) - Compatible with Java 17 (partial support for Java 11)
- Spring Boot 3.2 tested
- Tested with Spring for GraphQL 1.1+
- Implement
ErrorCodeper domain (e.g.,UserErrorCode,AuthErrorCode) - Override methods in
AbstractGlobalExceptionHandlerto handle custom scenarios - Extend
ObjectsUtilfor validating strings, collections, enums, etc.
- Java 17+
- Spring Boot 3.2+
- Jakarta Validation
- JUnit 5
- Spring for GraphQL 1.1+
MIT License
Copyright (c) 2024
μ μ¬ν GitHub
Contributions are welcome!
- π Found a bug?
- π‘ Have a new idea or improvement?
- π Want to improve documentation?
Thanks to the following people who have contributed to this project π
|
Fiat_lux Creator & Maintainer |
Seungnam Han Contributor |
Want to contribute? Feel free to submit a pull request or open an issue!
Letβs build something great together. π
Made with care by @hyeonjaez