Beginner · APIs and request handling · topic 10 of 54 · 25 min
Validating input
Explanation
Never trust input
Input is any data that comes from outside your server: the body, the query, path params, headers and cookies. Your own app may check the form, but people can send requests with tools like curl or Postman, or change the app. So the backend must check everything again.
Four kinds of checks
| Check | Question | Example |
|---|---|---|
| Required | Is it there? | name must be present |
| Type | Is it the right kind of value? | price must be a number, not "100" |
| Length or range | Is it too short, too long, too big? | name 2 to 50 letters; qty 1 to 10 |
| Format | Does it have the right shape? | mobile, PIN code, email |
Checking formats with regular expressions
A regular expression (regex) is a short pattern that describes the shape of some text. ^ means "start", $ means "end", [6-9] means "one digit from 6 to 9", and {9} means "exactly 9 times". The test method says whether some text fits the pattern.
const mobile = /^[6-9][0-9]{9}$/; // 10 digits, first is 6, 7, 8 or 9
const pin = /^[1-9][0-9]{5}$/; // 6 digits, first is not 0
const email = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; // something@something.something
console.log(mobile.test('9876543210')); // true
console.log(mobile.test('5876543210')); // false: starts with 5
console.log(pin.test('560001')); // true (Bengaluru)
console.log(pin.test('56001')); // false: only 5 digits
console.log(email.test('asha@example.in')); // true
console.log(email.test('asha@example')); // false: no dot after @Collect every error
Do not stop at the first problem. Check every field and collect the problems in a list, each with the field name and a clear message. Then the app can mark all the wrong boxes at once, and the user fixes everything in one go.
function validateProduct(body) {
const errors = [];
if (typeof body.name !== 'string' || body.name.trim().length < 2) {
errors.push({ field: 'name', message: 'Name must have at least 2 letters' });
}
if (typeof body.price !== 'number' || body.price <= 0) {
errors.push({ field: 'price', message: 'Price must be a number above 0' });
}
return errors;
}
console.log(validateProduct({ name: 'Tea', price: 140 })); // []
console.log(validateProduct({ name: ' ', price: '140' })); // two errors400 or 422?
Use 400 Bad Request when the request itself is broken: the body is not valid JSON, or it is not an object at all. Use 422 Unprocessable Content when the JSON is fine but a value breaks a rule, like a mobile number with 8 digits. Many teams use 400 for both. What matters most is that you choose one style and use it everywhere.
Watch the lesson
Validating input · 1/6
Rule number one of backends: never trust input. Anyone can send any request to your server.
Prefer a video by a teacher? Find free videos on “backend input validation best practices tutorial” on YouTube ↗
In real life: A job portal sign-up form
A job portal asks for name, email, mobile and PIN code. The phone app checks the form, but the backend checks again, because a bot could post directly to /v1/signup. When a user sends mobile 12345 and PIN 0110, the server answers 422 with two errors, one for mobile and one for pin, and the app marks both boxes in red with the messages.
{
"error": {
"code": "VALIDATION_FAILED",
"message": "Some fields are not valid",
"fields": [
{ "field": "mobile", "message": "Enter a 10-digit mobile number starting with 6, 7, 8 or 9" },
{ "field": "pin", "message": "Enter a 6-digit PIN code" }
]
}
}Practice (0/3 done)
Write a function isIndianMobile(value) that returns true only when value is a string of exactly 10 digits whose first digit is 6, 7, 8 or 9.
Write a function isPinCode(value) that returns true when value is a string of exactly 6 digits that does not start with 0.
Write validateSignup(body) that returns an array of errors, each { field, message }, in this order: "name" if name is not a string of 2 to 50 characters after trimming; "email" if email is not a string shaped like a@b.c; "mobile" if it is not a valid Indian mobile; "pin" if it is not a valid PIN code. Return [] when all is fine. body may be null.
Quick quiz
Read more (free)
Pass the quiz (60% or more) or mark this topic as done when you are ready.
Your progress is saved on this device only.