# Validation guide ## Single field — `tryCreate` Use at HTTP boundaries, form handlers, and message consumers when input may be invalid. ```typescript import { EmailAddress } from 'smart-value-objects'; const result = EmailAddress.tryCreate(req.body.email, 'email'); if (!result.ok) { return res.status(400).json({ errors: [{ path: result.error.path, message: result.error.message }], }); } const email = result.value; // EmailAddress instance ``` `create()` throws on invalid input — reserve for internal code after validation. ## Multi-field — `validateRecord` Aggregate every field error in one pass (no fail-fast per field). ```typescript import { validateRecord, requireRecordObject, Title, PersonName, EmailAddress, } from 'smart-value-objects'; const bodyResult = requireRecordObject(req.body, 'body'); if (!bodyResult.isValid) { return res.status(400).json({ errors: bodyResult.errors }); } const validation = validateRecord(req.body as Record, { title: Title.tryCreate, name: PersonName.tryCreate, email: EmailAddress.tryCreate, }); if (!validation.isValid) { return res.status(400).json({ errors: validation.errors }); } ``` ## Error shape Each `FieldError` has: | Field | Description | |-------|-------------| | `path` | Field name (e.g. `email`) | | `code` | Machine-readable code (`invalid_type`, `too_long`, `invalid_email`, …) | | `message` | Human-readable message | ## HTTP 400 mapping Map `validation.errors` directly to a problem-details or `{ field, message }[]` response. Same structure works for client-side forms when you reuse `validateRecord` on submit.