Validation checks incoming data before business logic accepts it. Network requests may be malformed or malicious, so allowing unchecked values through risks service interruption, inconsistent APIs, and garbage calculations. section 14.2.4
Separate the external API model from the justified domain model. The boundary converts untrusted request data into values that downstream logic can safely use. section 14.2.4
A practical validation design can proceed in stages:
- Check required fields and conditional fields at the request boundary; for example, reject an empty objectClass or code, and reject an empty name only when name is present. section 14.2.4
- Return a 400 Bad Request for invalid input instead of invoking business operations with incorrect values. section 14.2.4
- Replace scattered handler checks with applicative validators when rules must compose or report several failures together. section 14.2.4 section 14.3
- Preserve paths into nested structures so errors identify the malformed field rather than merely reporting that validation failed. section 14.3
Validating a request
A submitObjectTemplate handler checks name, objectClass, and code before calling createObjectTemplate. A failed check throws its corresponding error; only validated data reaches the business operation. section 14.2.4
Listing 14.13 Pointed validators
innerValidator :: Validator Inner
innerValidator = validator $ \inner -> Inner
<$> (inner ^. intField' #1
& condition (> 0) err1
&. condition (< 100)) err2
where
err1 = "Inner intField: should be > 0"
err2 = "Inner intField: should be < 100"
outerValidator :: Validator Outer
outerValidator = validator $ \outer -> Outer
<$> (outer ^. stringField' #2
& condition (not . null) err)
<*> (nested outer innerField' innerValidator)
where
err = "Outer stringField: should not be empty"
Pointed validators demonstrate field-level conditions, nested validation, and reconstruction of validated Outer and Inner values. section 14.2.4





























