Validation and Data Transformation
On this page
Someone will send you an email field with “lol”. Someone will put -5 as their age. Someone will try to inject SQL into your username field. And someone will send {"isAdmin": true} hoping you’re careless enough to save it directly.
Your job as a backend engineer: catch ALL of this before it gets anywhere near your database.
Why Validate?
Three reasons, all equally important:
Data integrity. Garbage in, garbage out. If invalid data gets into your database, everything downstream breaks. Reports are wrong. Queries fail. Other services consuming your data crash.
Security. SQL injection, XSS, command injection. All of them happen through unvalidated input. One missing check and an attacker owns your database.
User experience. Telling someone “email must be a valid email address” is infinitely better than a vague 500 Internal Server Error when PostgreSQL rejects the insert.
What to Validate
Every piece of incoming data needs checks:

Type: is it actually a string? A number? An array? Or did someone send null where you expected an object?
Presence: is this required field actually there? Missing email on a signup request should fail immediately.
Format: does this email look like an email? Is this date in ISO format? Does this phone number match a valid pattern?
Range: is age between 0 and 150? Is the page number positive? Is the quantity not greater than stock?
Length: is the username between 3 and 50 characters? Is the bio under 500 chars?
Business rules: does this coupon code exist? Is this time slot still available? Has this user already registered?
Data Transformation with DTOs
Raw client input should NEVER go directly to your database. You need a controlled intermediate step.

DTOs (Data Transfer Objects) define exactly what comes in and what goes out:
CreateUserDTO: what the client is allowed to send (email, password, name)Userentity: what lives in your database (id, email, passwordHash, createdAt, isAdmin)UserResponse: what you send back (id, email, name. Never the password hash. Never isAdmin.)
Why this matters:
If a client sends {"email": "a@b.com", "password": "123", "isAdmin": true} and you just dump the whole body into your database, congratulations, they just made themselves admin. DTOs prevent this by explicitly whitelisting which fields are accepted.
Sanitization vs Validation
Two different operations, both necessary:

Validation rejects bad data. “This is not a valid email, request denied.”
Sanitization cleans up data that’s acceptable but messy:
- Trim whitespace:
" shubham@email.com "becomes"shubham@email.com" - Lowercase emails:
"Shubham@Email.COM"becomes"shubham@email.com" - Strip HTML tags from text inputs
- Remove control characters
Always sanitize FIRST, then validate. Otherwise you might reject " valid@email.com " because of the spaces, even though the actual email is fine.
Error Responses That Don’t Suck
When validation fails, be specific. Don’t just say “Bad Request.” Tell the client exactly what’s wrong:
{
"errors": [
{"field": "email", "message": "must be a valid email address"},
{"field": "age", "message": "must be between 0 and 150"},
{"field": "name", "message": "is required"}
]
}
Return ALL validation errors at once. Nobody wants to fix one field, resubmit, discover another error, fix it, resubmit, find yet another error. Collect everything and return it in one shot.
Validation Libraries Worth Knowing
You don’t need to write regex for email validation from scratch. Use established libraries:
- JavaScript/TypeScript: Zod, Joi, class-validator
- Python: Pydantic, marshmallow
- Java: Bean Validation (javax.validation), Hibernate Validator
- Go: go-playground/validator
These handle 95% of validation needs out of the box. Define your schema once and the library does type checking, format validation, and error message generation for you.
Wrapping Up
- Never trust client input. Ever.
- Validate at the request boundary first (type, format, presence, range)
- Use DTOs to control which fields are accepted and exposed
- Sanitize before validating (trim, lowercase, strip)
- Return all errors at once with field-specific messages
- Database constraints are your safety net, not your strategy
- Use validation libraries, don’t reinvent the wheel
Day 7 of 95 | Backend Engineering Series