Spring Boot Service Contracts and Implementations
Overview
Create or update Spring Boot service interfaces and their implementations with consistent validation, nullness annotations, logging, and transactional boundaries.
Workflow
1) Locate or create the service interface
Place interfaces in the project’s service package (follow existing structure).
2) Apply interface contract rules
Annotate the interface with @Validated.
Annotate every method parameter with:
- •A JSpecify nullness annotation (
@NonNullor@Nullable) - •Jakarta Validation annotations as applicable
Parameter rules:
- •Required parameter:
@NonNull(or stronger, e.g.,@NotBlank,@Positive) - •Optional parameter:
@Nullable - •Request/DTO with nested validation:
@NonNull @Valid - •Collection parameters:
@NonNullon the collection and element constraints when relevant (e.g.,List<@NotBlank String>)
Use precise constraints:
- •Strings:
@NotBlank,@Size - •Numbers:
@Positive,@PositiveOrZero,@Min,@Max - •IDs (numeric):
@NonNull @Positive - •Pagination:
@Min(0)and/or@Positive
Always use imports for annotations (no fully-qualified names) unless there is a naming conflict.
3) Implement the service class
Annotate the implementation class with all of:
- •
@Service - •
@Slf4j - •
@RequiredArgsConstructor - •
@Transactional
Implementation rules:
- •Constructor injection only (via
@RequiredArgsConstructor) - •Use
logfor logging - •Do not use
var - •Do not use abbreviated variable names; prefer descriptive names
4) Wire dependencies and update usages
Inject only required collaborators.
Update call sites or tests as needed to satisfy the new contract annotations.
Quick checklist
- •Interface has
@Validated - •All parameters have
@NonNull/@Nullableand validation annotations - •Implementation has
@Service,@Slf4j,@RequiredArgsConstructor,@Transactional - •No
var, no abbreviated variable names, uselog