Skip to content

Latest commit

 

History

History
453 lines (333 loc) · 17.3 KB

File metadata and controls

453 lines (333 loc) · 17.3 KB

OG4Dev Spring API Response

Tech Stack

A lightweight, zero-configuration REST API Response wrapper for Spring Boot applications

Maven Central License Java Spring Boot Version

A lightweight, type-safe API Response wrapper for Spring Boot applications. Standardize your REST API responses with consistent structure, automatic timestamps, distributed tracing support, and clean factory methods. Features zero-configuration Spring Boot auto-configuration, opt-in automatic response wrapping (@AutoResponse), and production-ready exception handling with comprehensive RFC 9457 ProblemDetail support covering 10 common error scenarios. No external dependencies required - uses pure Java with a custom builder pattern.

🔗 Quick Links

📑 Table of Contents

🎯 Key Highlights

  • 🚀 Truly Zero Configuration - Spring Boot 3.x/4.x auto-configuration with META-INF imports
  • 🎁 Zero Boilerplate - Opt-in @AutoResponse to automatically wrap raw return types (Class or Method level)
  • 🎯 Production-Ready - Built-in RFC 9457 ProblemDetail with 10 comprehensive exception handlers
  • 🛡️ Complete Error Coverage - Handles validation, JSON parsing, 404s, method mismatches, media types, and more
  • 🔍 Trace IDs in Errors - Error responses include traceId for debugging
  • 🔒 Type-Safe & Immutable - Thread-safe design with generic type support
  • 📦 Ultra-Lightweight - Only ~10KB JAR size with provided dependencies
  • 🔍 Microservices-Ready - Built-in trace IDs for distributed tracing
  • Battle-Tested - Used in production Spring Boot applications
  • 📋 Professional-Grade Javadoc - 100% coverage with comprehensive method documentation
  • 🔐 Opt-in Security Features - Fine-grained control with field and class-level annotations
  • 🚫 Zero External Dependencies - Pure Java, no Lombok required

✨ Features

  • 🎯 Consistent Structure - All responses follow the same format: status, message, content, timestamp
  • 🎁 @AutoResponse Wrapping - Return plain DTOs; let the library wrap them automatically (Opt-in)
  • 🔒 Type-Safe - Full generic type support with compile-time type checking
  • 🔍 Distributed Tracing - Trace IDs in error responses with MDC integration for request tracking
  • Auto Timestamps - Automatic RFC 3339 UTC formatted timestamps on every response
  • 🏭 Factory Methods - Clean static methods: success(), created(), status()
  • 🚀 Zero Config - Spring Boot Auto-Configuration for instant setup
  • 🪶 Lightweight - Only ~10KB JAR with single provided dependency (Spring Web)
  • 📦 Immutable - Thread-safe with final fields
  • 🔌 Spring Native - Built on ResponseEntity and HttpStatus
  • 📋 RFC 9457 Compliance - Standard ProblemDetail format (supersedes RFC 7807)
  • 📚 Complete JavaDoc - Every class and method fully documented with comprehensive examples
  • 🔐 Opt-in Security Features - Fine-grained JSON request protection via field and class-level annotations
  • Strict JSON Validation - Rejects unknown properties to prevent mass assignment attacks (automatic)
  • XSS Prevention - HTML tag detection and rejection via @XssCheck annotation (opt-in)
  • Smart String Trimming - Whitespace trimming via @AutoTrim annotation (opt-in)
  • Case-Insensitive Enums - Flexible enum handling for better API usability (automatic)
  • 🛡️ Comprehensive Exception Handling - 10 built-in handlers covering all common scenarios

📦 Requirements

  • Java 17 or higher
  • Spring Boot 3.2.0 or higher (tested up to 4.0.3)
  • No additional dependencies required (pure Java implementation)

🌟 What Makes This Different?

Unlike other response wrapper libraries, this one offers:

  • Native Spring Boot 3.x/4.x Auto-Configuration - No manual setup required
  • Zero-Boilerplate @AutoResponse - Return raw objects, let the library wrap them automatically while preserving your HTTP Status codes. Supports both Class-level and Method-level granularity.
  • Intelligent String Handling - Safely wraps raw String returns into JSON without throwing ClassCastException.
  • RFC 9457 ProblemDetail Support - Industry-standard error responses (latest RFC)
  • Opt-in Security Features - Fine-grained control via field and class-level annotations (@XssCheck, @AutoTrim)
  • Zero External Dependencies - Pure Java implementation, won't conflict with your application
  • Extensible Exception Handling - Create custom business exceptions easily
  • Trace ID Support - Built-in distributed tracing capabilities
  • Professional-Grade Documentation - 100% Javadoc coverage

🚀 Installation

Maven (Latest - v1.4.0)

<dependency>
    <groupId>io.github.og4dev</groupId>
    <artifactId>og4dev-spring-response</artifactId>
    <version>1.4.0</version>
</dependency>

Gradle (Latest - v1.4.0)

implementation 'io.github.og4dev:og4dev-spring-response:1.4.0'

Gradle Kotlin DSL (Latest - v1.4.0)

implementation("io.github.og4dev:og4dev-spring-response:1.4.0")

📁 Project Structure

The library is organized into six main packages:

io.github.og4dev
├── advice/
│   └── GlobalResponseWrapper.java           # Automatic response wrapper interceptor
├── annotation/
│   ├── AutoResponse.java                    # Opt-in annotation for automatic wrapping
│   ├── AutoTrim.java                        # Opt-in annotation for string trimming
│   └── XssCheck.java                        # Opt-in annotation for XSS validation
├── config/
│   └── ApiResponseAutoConfiguration.java    # Spring Boot auto-configuration
├── dto/
│   └── ApiResponse.java                     # Generic response wrapper
├── exception/
│   ├── ApiException.java                    # Abstract base for custom exceptions
│   └── GlobalExceptionHandler.java          # RFC 9457 exception handler
└── filter/
    └── TraceIdFilter.java                   # Request trace ID generation

🎯 Quick Start

You can use the library in two ways: Explicit Factory Methods or Automatic Wrapping.

Method 1: Explicit Factory Methods

@RestController
@RequestMapping("/api/users")
public class UserController {
    @GetMapping("/{id}")
    public ResponseEntity<ApiResponse<User>> getUser(@PathVariable Long id) {
        User user = userService.findById(id);
        return ApiResponse.success("User retrieved successfully", user);
    }
}

Method 2: Automatic Wrapping (New in v1.4.0) 🎁

Tired of typing ResponseEntity<ApiResponse<T>>? Use @AutoResponse! You can apply it to the whole class, or just specific methods.

@RestController
@RequestMapping("/api/users")
// @AutoResponse // Uncomment this to apply to ALL methods in the controller
public class UserController {

    @AutoResponse // Applied ONLY to this specific method
    @GetMapping("/{id}")
    public User getUser(@PathVariable Long id) {
        // Just return the raw object!
        return userService.findById(id);
    }

    @AutoResponse
    @PostMapping
    @ResponseStatus(HttpStatus.CREATED) // Preserves custom status codes!
    public User createUser(@RequestBody UserDto dto) {
        return userService.create(dto);
    }

    @AutoResponse
    @GetMapping("/greeting")
    public String greeting() {
        // Raw strings are safely converted to JSON ApiResponse too!
        return "Hello World"; 
    }
}

Both methods produce the exact same JSON:

{
  "status": 200,
  // or 201 for POST
  "message": "Success",
  "content": {
    "id": 1,
    "name": "John Doe"
  },
  "timestamp": "2026-02-28T10:30:45.123Z"
}

⚙️ Auto-Configuration

The library features Spring Boot Auto-Configuration for truly zero-config setup!

GlobalExceptionHandler - Automatic exception handling ✅ GlobalResponseWrapper - Automatic payload wrapping via @AutoResponseSecurity Customizers - Jackson configuration for @AutoTrim and @XssCheck

No configuration needed! Just add the dependency.

🎁 Opt-in Automatic Wrapping (@AutoResponse)

Introduced in v1.4.0, you can eliminate boilerplate code by letting the library wrap your controller responses automatically.

Flexible Granularity:

  • Class Level (@Target(ElementType.TYPE)): Apply @AutoResponse to your controller class to automatically wrap all endpoint responses within it.
  • Method Level (@Target(ElementType.METHOD)): Apply @AutoResponse to specific request mapping methods for fine-grained, opt-in control over exactly which endpoints get wrapped.

Key Capabilities:

  • Status Code Preservation: Intelligently reads custom HTTP status codes set via @ResponseStatus (e.g., 201 Created) and reflects them in the ApiResponse.
  • Double-Wrap Prevention: Safely skips wrapping if you explicitly return an ApiResponse or ResponseEntity.
  • Error Compatibility: Bypasses ProblemDetail responses, ensuring standard error handling is never broken.
  • Intelligent String Handling: Uses the injected ObjectMapper to serialize raw String returns into JSON format safely, preventing ClassCastException conflicts with Spring's native StringHttpMessageConverter.

🔐 Built-in Security Features

The library provides fine-grained security and data processing features through field-level annotations. By default, fields are NOT modified unless explicitly annotated.

New in v1.4.0: You can now apply @AutoTrim and @XssCheck to entire classes to protect all string fields at once!

1. Strict Property Validation 🛡️ (Automatic)

Rejects JSON payloads containing unexpected fields to prevent mass assignment attacks.

2. Opt-in XSS Prevention with @XssCheck 🔒

Fail-fast HTML tag detection and rejection using regex pattern (?s).*<\s*[a-zA-Z/!].*.

@XssCheck
private String comment; // Rejects "<script>alert(1)</script>"

3. Opt-in String Trimming with @AutoTrim ✂️

Automatic whitespace removal for specific fields.

@AutoTrim
private String username; // "  john_doe  " -> "john_doe"

4. Class-Level Protection (New in v1.4.0) 🛡️

Apply annotations to the class level to automatically protect ALL string fields within that class!

@AutoTrim
@XssCheck
public class SecureRegistrationDTO {
    // Both of these fields will be automatically trimmed and XSS-validated!
    private String username;
    private String email;
    private String bio;
}

(See full Security details in the Javadocs and examples above).

🛡️ Built-in Exception Handling

The library includes a **production-ready GlobalExceptionHandler** that automatically handles 10 common exceptions using Spring Boot's ProblemDetail (RFC 9457) standard.

  • Automatic Logging: SLF4J integration for all errors.
  • Trace ID Consistency: Logs and responses always have matching trace IDs.
  • Custom Business Exceptions: Extend the abstract ApiException class to create domain-specific exceptions.
public class ResourceNotFoundException extends ApiException {
    public ResourceNotFoundException(String resource, Long id) {
        super(String.format("%s not found with ID: %d", resource, id), HttpStatus.NOT_FOUND);
    }
}

🌍 Real-World Examples

Example 1: Clean CRUD Controller (Using Class-Level @AutoResponse)

@RestController
@RequestMapping("/api/products")
@RequiredArgsConstructor
@AutoResponse // ✨ Zero boilerplate for the whole controller!
public class ProductController {

    private final ProductService productService;

    @GetMapping
    public Page<Product> getAllProducts(Pageable pageable) {
        return productService.findAll(pageable);
    }

    @GetMapping("/{id}")
    public Product getProduct(@PathVariable Long id) {
        return productService.findById(id)
                .orElseThrow(() -> new ResourceNotFoundException("Product", id));
    }

    @PostMapping
    @ResponseStatus(HttpStatus.CREATED) // ✨ 201 Created preserved automatically
    public Product createProduct(@Valid @RequestBody ProductDto dto) {
        return productService.create(dto);
    }

    @DeleteMapping("/{id}")
    public void deleteProduct(@PathVariable Long id) {
        productService.delete(id);
        // Returns empty content with 200 OK automatically
    }
}

📚 API Reference

(Refer to Javadoc for full details)

📈 Version History

1.4.0 (February 2026) - Current Release

New Features & Improvements:

  • @AutoResponse Annotation & GlobalResponseWrapper

  • Opt-in automatic response wrapping to eliminate boilerplate code.

  • Improved Granularity: Fully supports both Class-level (ElementType.TYPE) and Method-level (ElementType.METHOD) placement for precision control over which endpoints are wrapped.

  • Returns raw DTOs from controllers and automatically wraps them in ApiResponse<T>.

  • Preserves HTTP status codes from @ResponseStatus.

  • Intelligently skips ResponseEntity, ApiResponse, and ProblemDetail to prevent double-wrapping.

  • Intelligent String Handling: Uses Spring's ObjectMapper to safely serialize raw String returns to JSON, avoiding ClassCastException with native converters.

  • Class-Level Security Annotations

  • @AutoTrim and @XssCheck can now be applied at the Class level (ElementType.TYPE) to automatically protect all String fields within the DTO at once.

  • Documentation

  • package-info.java documentation added for the new advice package.

1.3.0 (February 2026)

  • Security Philosophy Change: Complete redesign from automatic to opt-in approach for JSON sanitization.
  • Added @AutoTrim annotation for explicit string trimming.
  • Added @XssCheck annotation for explicit fail-fast XSS validation.
  • Extensive Javadoc and README updates regarding the new security model.

1.2.0 (February 2026)

  • Added @NoTrim annotation (Legacy - removed in 1.3.0 in favor of opt-in model).
  • Enhanced Advanced String Deserializer.

1.1.0 & 1.1.1 (February 2026)

  • Added GlobalExceptionHandler and RFC 9457 Support.
  • Added TraceIdFilter and MDC Integration.
  • Verified Spring Boot 4.0.3 Compatibility.

1.0.0 (February 2026)

  • Initial Release. Core ApiResponse wrapper.

🤝 Contributing

We welcome contributions! Please see the Contributing section above for details on our Apache 2.0 license terms and PR process.

📄 License

Licensed under the Apache License 2.0.

📧 Contact

Pasindu OG | pasinduogdev@gmail.com | GitHub: @pasinduog


⭐ If you find this library helpful, please give it a star on GitHub!