principleModeratepending
Principle: Parse, don't validate
Viewed 0 times
parse don't validatetype safetyboundary validationzodpydantic
Problem
Code validates data at the boundary but continues using untyped/raw data internally, requiring re-validation at every use site.
Solution
Transform raw data into typed structures at the boundary:
The principle:
Libraries that embody this:
Benefits:
## Validate (bad pattern):
function processOrder(data: unknown) {
if (!isValidOrder(data)) throw new Error('Invalid');
// data is still 'unknown' or 'any'
// Every function that receives it must re-check
saveOrder(data); // saveOrder has to validate again?
}
## Parse (good pattern):
function parseOrder(data: unknown): Order {
// Parse once, return typed result
if (typeof data !== 'object') throw new ParseError(...);
const amount = parseFloat(data.amount);
if (isNaN(amount)) throw new ParseError(...);
return {
id: parseUUID(data.id),
amount,
items: data.items.map(parseOrderItem),
createdAt: new Date(data.created_at),
};
}
// Now the rest of your code works with Order type
// No more checking, no more 'as any', no more null checks
function processOrder(order: Order) {
// order.amount is definitely a number
// order.id is definitely a valid UUID
// order.items is definitely an array of OrderItems
saveOrder(order); // saveOrder trusts the type
}The principle:
- At system boundaries: parse raw data into domain types
- Inside the system: trust the types
- Never pass raw/untyped data past the boundary
Libraries that embody this:
- Zod (TypeScript)
- Pydantic (Python)
- serde (Rust)
- Elm's JSON decoders
Benefits:
- Validation logic lives in ONE place
- Invalid states are unrepresentable after parsing
- No defensive checks scattered through business logic
- Type system proves data is valid
Why
Alexis King's principle. Parsing produces a value that carries proof of validity in its type. Validation just returns a boolean, leaving the data unchanged and requiring re-validation everywhere.
Context
Data handling at system boundaries
Revisions (0)
No revisions yet.