REST API Input Validation

Every request carries data that the server did not create. Some of it is correct, some of it is careless, and some of it is crafted to cause harm. Input validation checks data at the door before the application uses it.

The Airport Check Picture

Airports inspect every bag before passengers board. Inspectors do not assume that every traveler means well. They check each item against clear rules. A server treats incoming requests the same way, and it checks every field before processing.

Where Validation Happens

Request arrives
     │
     ▼
1. Syntax check     Is the body valid JSON?
2. Structure check  Are required fields present, with the right types?
3. Rule check       Are values within allowed ranges and formats?
4. Business check   Does the action make sense for this user and state?
     │
     ▼
Pass: process the request       Fail: return an error response

Client Checks vs Server Checks

Forms in apps and browsers can validate fields to give instant feedback. Those checks improve the user experience, and they offer no protection. Anyone can skip the form and call the API directly. The server must validate every request on its own.

What to Validate

CheckSample Rule
Typeage must be a whole number
Requiredemail must be present
Lengthname holds 1 to 100 characters
Rangequantity holds a number from 1 to 500
Formatemail matches an address pattern
Allowed liststatus equals pending, paid, or shipped
Sizerequest body stays under 1 MB

Allowlists Beat Blocklists

A blocklist names bad values, and attackers invent new ones. An allowlist names the good values and rejects everything else. Accept only known fields, known types, and known choices.

Reject Unknown Fields

A client might send an extra field such as "role": "admin" in a profile update. A server that copies every incoming field into the database hands out privileges for free. Map each accepted field by name and ignore or reject the rest.

Protect Against Injection

Never build database queries by joining strings with user input. Use parameterized queries, where the database receives the command and the values separately.

Risky:  "SELECT * FROM users WHERE email = '" + input + "'"
Safe:   "SELECT * FROM users WHERE email = ?"   with value from input

Encode output that reaches web pages, and avoid passing input into shell commands or file paths.

Choose the Right Status Code

  • 400 Bad Request: the body is not valid JSON, or a required structure is broken.
  • 422 Unprocessable Content: the JSON is valid and a field breaks a rule.
  • 413 Content Too Large: the body exceeds the size limit.
  • 415 Unsupported Media Type: the format is not accepted.

Report All Errors at Once

A response that lists every problem saves users from fixing one error per attempt.

HTTP/1.1 422 Unprocessable Content

{
  "error": "validation_failed",
  "details": [
    { "field": "email", "message": "must be a valid address" },
    { "field": "quantity", "message": "must be between 1 and 500" }
  ]
}

Write messages that describe the rule, and leave out internal details such as stack traces or table names.

Normalize Before Checking

Trim spaces, convert text to a consistent Unicode form, and lowercase email addresses before applying rules. Normalization removes sneaky variations that slip past checks.

Common Mistakes

Trusting the Front End

Browser checks vanish when someone calls the API with a script. Validate on the server every time.

Validating Only Some Endpoints

A forgotten endpoint becomes the weak spot. Use shared validation schemas, such as JSON Schema, across all routes.

Vague Errors

A message that says "invalid input" helps nobody. Name the field and the rule.