# Validator

> Validator Layer

- Skill: `harshamendu/validator` (Agent Skill, multi-file: 13 files)
- Install (CLI): `npx skillmds@latest add harshamendu/validator`
- Raw SKILL.md: https://api.skillmd.com/api/skills/harshamendu/validator/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: Harshamendu (https://skillmd.com/u/harshamendu)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/harshamendu/validator

---

# Validator Layer

> **📝 Note:** This guide uses generic placeholder names to be reusable across any Spring Boot microservice.
> Replace with your actual implementation:
> - `{YourService}` → Your service name (e.g., `OrderService`, `PaymentService`)
> - `BusinessService` → Your core service (e.g., `OrderService`, `UserService`)
> - `DataService` → Your data processing service (e.g., `PaymentService`, `InventoryService`)
> - `IntegrationService` → Your external integration (e.g., `PaymentGatewayService`)
> - `{RequestType}` → Your request DTO (e.g., `CreateOrderRequest`)
> - `{ResponseType}` → Your response DTO (e.g., `OrderResponse`)


## Purpose
The validator layer centralizes all input validation logic. It validates HTTP headers, request parameters, and business rules before data reaches the service layer, ensuring fail-fast behavior and consistent error messages.

## Architecture
- **Validator Component Pattern**: Spring `@Component` validators injected into controllers
- **Fail-Fast Validation**: Validate all inputs before processing
- **Single Responsibility**: Each validation method has one clear purpose
- **Consistent Error Messages**: Standardized exception types and messages

## Package Structure
```
validator/
└── RequestValidator.java    # Centralized validation logic
```

## Quick Reference

### Basic Validator Pattern
```java
@Component
public class RequestValidator {
    public void validateEmail(String email) {
        if (StringUtils.isBlank(email)) {
            throw new BadRequestException("Email is required");
        }
        if (!EMAIL_PATTERN.matcher(email).matches()) {
            throw new BadRequestException("Email format is invalid");
        }
    }
}
```

### Controller Integration
```java
@RestController
public class BusinessApiImpl {
    private final RequestValidator validator;
    
    @Override
    public ResponseEntity<Response> endpoint(String param) {
        // Validate first
        validator.validateParam(param);
        
        // Process with valid inputs
        return ResponseEntity.ok(service.process(param));
    }
}
```

### Validation Types
- **Required Field**: Check null/blank values
- **Format**: Email, UUID, country code patterns
- **Range**: Min/max value validation
- **Enum**: Whitelist of valid values
- **Conditional**: Business rule-based validation

### Common Utilities
```java
// Apache Commons Lang
StringUtils.isBlank(str)        // null, empty, or whitespace
StringUtils.isEmpty(str)        // null or empty

// Pre-compiled patterns
private static final Pattern EMAIL_PATTERN = 
    Pattern.compile("^[A-Za-z0-9+_.-]+@(.+)$");
```

### Testing Pattern
```java
@Test
void testValidate_Valid() {
    assertDoesNotThrow(() -> validator.validate("valid-input"));
}

@Test
void testValidate_Invalid() {
    BadRequestException ex = assertThrows(
        BadRequestException.class,
        () -> validator.validate(null)
    );
    assertEquals("Field is required", ex.getMessage());
}
```

## Key Principles

### ✅ DO
- Validate all inputs before processing
- Use specific exception types (BadRequestException)
- Write descriptive error messages
- Pre-compile regex patterns
- Test happy path and error cases
- Order validations by cost (cheap first)

### ❌ DON'T
- Validate in service layer (keep in validators)
- Return boolean (throw exceptions instead)
- Use generic error messages
- Make expensive calls (DB, API) in validators
- Duplicate validation logic

## Documentation

### Detailed Guides
- **[Patterns](guides/patterns.md)** - Architectural patterns and design approaches
- **[Best Practices](guides/best-practices.md)** - Coding standards and conventions
- **[Testing](guides/testing.md)** - Comprehensive testing strategies
- **[Anti-Patterns](guides/anti-patterns.md)** - Common mistakes to avoid

### Code Examples
See [examples/](examples/) for complete, working code:
- `RequestValidator.java` - Full validator implementation
- `BusinessApiImpl.java` - Controller integration
- `RequestValidatorTest.java` - Comprehensive test suite
- Supporting classes (exceptions, services, etc.)

Package: `com.example.microserviceorch.validator.example`

## Code Formatting
All Java code is formatted using **Spotless** with Google Java Format (AOSP style).

```bash
./gradlew spotlessApply
```

## Summary
The validator layer ensures:
- **Reliability**: All invalid inputs are caught early
- **Consistency**: Standardized validation across endpoints
- **Maintainability**: Centralized, reusable validation logic
- **Security**: Proper input sanitization and validation
- **Performance**: Fast, efficient validation checks

For detailed information on specific topics, see the guides above.

