Card 05/ 10
Validating Input at the Boundary
Every value from a client is checked for type, range and size before the code behind the API sees it.
Every value a client sends is untrusted until it is checked. Input validation at the boundary means checking each request against the contract, its types, formats, ranges, lengths and counts, before any business logic runs, and refusing the request with a 400 or 422 that names the field. A value that passed validation can be trusted to be the right shape; one that did not never reaches the code behind the API.
| Field | Rule checked | Error returned |
|---|---|---|
| quantity | An integer from 1 to 100 | 422, /quantity must be between 1 and 100 |
| A valid address, at most 254 characters | 422, /email is not a valid address | |
| items | An array of 1 to 50 entries | 422, /items has more than 50 entries |
| note | A string of at most 500 characters | 422, /note is longer than 500 characters |
| The whole body | At most 100 KB, valid JSON, no unknown fields | 413 Content Too Large, or 400 |
What goes wrong. Without validation, a negative quantity produces a refund, a 50 MB string fills memory or a log, an array of a million items ties up a worker, and a value of the wrong type crashes a handler with a 500 that reveals the stack.
A request that shows it. POST /orders with "quantity": -5, or a note of a million characters.
The fix. Validate against a schema at the edge, the same one the contract publishes, using a validation library rather than hand-written checks. Set limits on everything that can grow: body size, string length, array length, and query values such as limit on a list. Prefer allow-lists of valid values to block-lists of bad ones.
Validation is not the whole defence. It checks shape, not meaning. Parameterised queries still prevent SQL injection, and output encoding still prevents script injection, whatever validation passed.
How to test. Send each field its boundary values, just inside and just outside the range, the wrong type, an empty value and an oversized one, and check each gets the documented error.
So check every value against the contract before it reaches the code, and put a limit on everything that can grow.
← → move through sections and cards