Spring Boot Patterns
Spring Boot 3.x best practices for enterprise Java APIs. Architecture and clarity over framework tricks.
Selective Reading Rule
Read only files relevant to the request. Use the content map to focus.
Content Map
| File | Description | When to Read |
|---|---|---|
layered-arch.md | Controller -> Service -> Repository | Architecture design |
rest-api.md | REST endpoints, DTOs, validation | API development |
configuration.md | @ConfigurationProperties, profiles | Config and envs |
exceptions.md | @ControllerAdvice, ProblemDetail | Error handling |
observability.md | Actuator, logging, metrics | Production readiness |
Core Patterns
1. Layered Architecture
code
Controller -> Service -> Repository
Keep controllers thin, services own business rules, repositories focus on data access.
2. REST Controller + DTOs
java
@RestController
@RequestMapping("/api/v1/users")
@RequiredArgsConstructor
@Validated
public class UserController {
private final UserService userService;
@GetMapping("/{id}")
public UserResponse findById(@PathVariable String id) {
return userService.findById(id)
.map(UserResponse::from)
.orElseThrow(() -> new ResourceNotFoundException("User", id));
}
@PostMapping
@ResponseStatus(HttpStatus.CREATED)
public UserResponse create(@Valid @RequestBody CreateUserRequest request) {
return UserResponse.from(userService.create(request.toCommand()));
}
}
public record CreateUserRequest(
@NotBlank @Email String email,
@NotBlank @Size(min = 2, max = 100) String name
) {
public CreateUserCommand toCommand() {
return new CreateUserCommand(email, name);
}
}
3. Configuration Properties
java
@ConfigurationProperties(prefix = "app")
@Validated
public record AppProperties(
@NotBlank String name,
@NotNull SecurityProperties security
) {
public record SecurityProperties(
@NotBlank String jwtSecret,
@Positive int jwtExpirationMinutes
) {}
}
4. Error Handling
java
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(ResourceNotFoundException.class)
public ProblemDetail handleNotFound(ResourceNotFoundException ex) {
return ProblemDetail.forStatusAndDetail(HttpStatus.NOT_FOUND, ex.getMessage());
}
}
Decision Checklist
- •Layered architecture respected?
- •DTOs separated from entities?
- •Validation at API boundary?
- •Exceptions centralized?
- •Config externalized?
Anti-Patterns
| Anti-Pattern | Why Bad | Better Approach |
|---|---|---|
| Business logic in controller | Hard to test | Move to service |
| Field injection | Hidden deps | Constructor injection |
| Entity in response | Leaks internals | DTO pattern |
| open-in-view true | Hidden queries | Fetch explicitly |
Related Skills
| Need | Skill |
|---|---|
| Data access | @[skills/spring-data-jpa] |
| Security | @[skills/spring-security] |
| Testing | @[skills/spring-testing] |