Boundary Validation
Boundary validation ensures numeric, length, size, and collection values remain within explicitly defined limits. It prevents invalid inputs from reaching business logic or downstream systems.
Boundary validation checks whether an input falls inside an allowed minimum and maximum, or satisfies an allowed size range. Typical examples include requiring an age between 18 and 120, a username with 3 to 30 characters, or a collection containing at most 100 elements.
A boundary can be inclusive or exclusive. For example, `0 <= quantity && quantity <= 100` accepts both endpoints, while `0 < quantity && quantity < 100` rejects them. The intended rule should be explicit so that edge cases such as exactly `0`, `100`, or an empty collection are handled correctly.
In Java backend applications, validation can be implemented with explicit checks or Bean Validation annotations such as `@Min`, `@Max`, `@Size`, and `@DecimalMin`. Validation should occur at an appropriate input boundary, such as a controller or request DTO, while domain invariants may also need enforcement deeper in the application.
Boundary validation is especially important because ordinary valid-looking inputs can fail exactly at the limits. Tests should therefore cover values below the minimum, exactly at the minimum, normal values, exactly at the maximum, and above the maximum.
Key points
- Define minimum and maximum limits explicitly.
- Decide whether each endpoint is inclusive or exclusive.
- Validate numeric values, strings, arrays, and collections according to their relevant limits.
- Test values immediately below, at, and immediately above each boundary.
- Use Bean Validation annotations when they express the constraint clearly.
Interview questions
What is boundary validation?
Boundary validation checks that an input stays within an allowed range or size. For example, a quantity might be required to be between 1 and 100 inclusive. It applies to numbers as well as lengths and collection sizes. The important part is defining and testing the exact endpoints.
How would you test a range from 1 to 100?
I would test values below the minimum, at the minimum, a normal value, at the maximum, and above the maximum. That means examples such as 0, 1, 50, 100, and 101. These cases verify both rejection boundaries and accepted endpoints.
How can boundary validation be implemented in a Java backend?
For simple checks, Java code can compare a value against explicit limits. For request DTOs, Jakarta Bean Validation can express common constraints using annotations such as `@Min`, `@Max`, and `@Size`. A controller can trigger validation on incoming request objects, while domain code should still protect important invariants that cannot safely be delegated to the transport layer.
What boundary cases are easy to miss in API validation?
Developers often forget whether the minimum and maximum are inclusive, or they test only ordinary values. Empty strings and empty collections can also be overlooked when size constraints are involved. Another common issue is validating the request DTO but allowing another code path to construct an invalid domain object.
What is the difference between boundary validation and a business invariant?
Boundary validation commonly protects an application from malformed or out-of-range external input. A business invariant is a rule that must hold for a valid domain state, regardless of whether the object came from an HTTP request, a message, a batch job, or internal code. Some boundary checks directly correspond to domain invariants, but they are not interchangeable concepts. Important invariants should therefore not depend solely on controller-level validation.