Bird
Raised Fist0
Expressframework~20 mins

Schema validation in Express - Practice Problems & Coding Challenges

Choose your learning style10 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Challenge - 5 Problems
🎖️
Schema Validation Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
component_behavior
intermediate
2:00remaining
What happens when a request body misses a required field in this Express schema validation?

Consider this Express middleware using express-validator to validate a POST request body:

const { body, validationResult } = require('express-validator');

app.post('/user', [
  body('username').isString().notEmpty(),
  body('age').isInt({ min: 18 })
], (req, res) => {
  const errors = validationResult(req);
  if (!errors.isEmpty()) {
    return res.status(400).json({ errors: errors.array() });
  }
  res.send('User created');
});

What will the server respond if the request body is { "username": "alice" } (missing age)?

Express
const { body, validationResult } = require('express-validator');

app.post('/user', [
  body('username').isString().notEmpty(),
  body('age').isInt({ min: 18 })
], (req, res) => {
  const errors = validationResult(req);
  if (!errors.isEmpty()) {
    return res.status(400).json({ errors: errors.array() });
  }
  res.send('User created');
});
AResponds with status 400 and an error about missing 'age' field
BResponds with status 200 and message 'User created'
CResponds with status 500 due to server error
DResponds with status 400 and an error about missing 'username' field
Attempts:
2 left
💡 Hint

Think about what happens when a required field is not present and the validation rule expects an integer.

📝 Syntax
intermediate
2:00remaining
Identify the syntax error in this Express schema validation middleware

Look at this Express route with schema validation using express-validator:

app.post('/login', [
  body('email').isEmail(),
  body('password').isLength({ min: 6 })
], (req, res) => {
  const errors = validationResult(req)
  if (!errors.isEmpty()) {
    return res.status(400).json({ errors: errors.array() })
  }
  res.send('Login successful')
})

What is the syntax error in this code?

Express
app.post('/login', [
  body('email').isEmail(),
  body('password').isLength({ min: 6 })
], (req, res) => {
  const errors = validationResult(req)
  if (!errors.isEmpty()) {
    return res.status(400).json({ errors: errors.array() })
  }
  res.send('Login successful')
})
AMissing semicolons after statements inside the route handler
BMissing parentheses after 'validationResult' call
CMissing import of 'body' and 'validationResult' from 'express-validator'
DMissing closing bracket for the array of validation middlewares
Attempts:
2 left
💡 Hint

Check if all required functions are imported before usage.

🔧 Debug
advanced
2:00remaining
Why does this Express schema validation not catch invalid email input?

Given this Express route:

const { body, validationResult } = require('express-validator');

app.post('/register', [
  body('email').isEmail(),
  body('password').isLength({ min: 8 })
], (req, res) => {
  const errors = validationResult(req);
  if (!errors.isEmpty()) {
    return res.status(400).json({ errors: errors.array() });
  }
  res.send('Registration successful');
});

But when sending { "email": "not-an-email", "password": "12345678" }, the server responds with 'Registration successful'. Why?

Express
const { body, validationResult } = require('express-validator');

app.post('/register', [
  body('email').isEmail(),
  body('password').isLength({ min: 8 })
], (req, res) => {
  const errors = validationResult(req);
  if (!errors.isEmpty()) {
    return res.status(400).json({ errors: errors.array() });
  }
  res.send('Registration successful');
});
AThe isEmail() validator is not working because the password is valid
BThe route handler does not return after sending the error response
CThe validationResult is not called correctly
DThe request body is not parsed as JSON before validation, so fields are undefined
Attempts:
2 left
💡 Hint

Think about how Express reads the request body before validation.

state_output
advanced
2:00remaining
What is the output of this Express validation error response?

Consider this Express route with validation:

const { body, validationResult } = require('express-validator');

app.post('/submit', [
  body('title').isLength({ min: 5 }),
  body('year').isInt({ min: 2000, max: 2025 })
], (req, res) => {
  const errors = validationResult(req);
  if (!errors.isEmpty()) {
    return res.status(422).json({ errors: errors.array() });
  }
  res.send('Submission accepted');
});

If the request body is { "title": "abc", "year": 1999 }, what is the JSON response?

Express
const { body, validationResult } = require('express-validator');

app.post('/submit', [
  body('title').isLength({ min: 5 }),
  body('year').isInt({ min: 2000, max: 2025 })
], (req, res) => {
  const errors = validationResult(req);
  if (!errors.isEmpty()) {
    return res.status(422).json({ errors: errors.array() });
  }
  res.send('Submission accepted');
});
A{"errors":[{"value":"abc","msg":"Title must be at least 5 characters long","param":"title","location":"body"},{"value":1999,"msg":"Year must be between 2000 and 2025","param":"year","location":"body"}]}
B{"errors":[{"value":"abc","msg":"Invalid value","param":"title","location":"body"},{"value":1999,"msg":"Invalid value","param":"year","location":"body"}]}
C{"errors":[{"value":"abc","msg":"Too short","param":"title","location":"body"}]}
D{"errors":[]}
Attempts:
2 left
💡 Hint

Check the default error messages from express-validator when no custom message is provided.

🧠 Conceptual
expert
2:00remaining
Which option best explains why schema validation middleware must run before route handlers in Express?

In Express, why is it important to place schema validation middleware before the main route handler?

ABecause validation middleware checks and rejects invalid input early, preventing the handler from processing bad data
BBecause validation middleware modifies the request body to match the schema before the handler uses it
CBecause route handlers cannot access <code>req.body</code> unless validation middleware runs first
DBecause validation middleware automatically sends success responses if validation passes, so handlers are skipped
Attempts:
2 left
💡 Hint

Think about the flow of request processing and error handling.

Practice

(1/5)
1. What is the main purpose of schema validation in an Express app?
easy
A. To store data permanently in the database
B. To speed up the server response time
C. To style the user interface automatically
D. To check if incoming data matches expected rules before processing

Solution

  1. Step 1: Understand schema validation role

    Schema validation ensures data received matches rules like type and format.
  2. Step 2: Identify main purpose in Express

    It prevents bad data from causing errors or security issues by checking before use.
  3. Final Answer:

    To check if incoming data matches expected rules before processing -> Option D
  4. Quick Check:

    Schema validation = data check before use [OK]
Hint: Schema validation means checking data fits rules before use [OK]
Common Mistakes:
  • Thinking validation speeds up server
  • Confusing validation with UI styling
  • Assuming validation stores data
2. Which of the following is the correct way to define a Joi schema for a required string named username?
easy
A. const schema = Joi.object({ username: Joi.string().required() });
B. const schema = Joi.string().required();
C. const schema = Joi.string().optional();
D. const schema = Joi.number().required();

Solution

  1. Step 1: Recall Joi schema structure for objects

    Joi schemas for objects use Joi.object({ key: rule }) format.
  2. Step 2: Check correct rule for required string property

    Property username must be a string and required, so use Joi.string().required().
  3. Final Answer:

    const schema = Joi.object({ username: Joi.string().required() }); -> Option A
  4. Quick Check:

    Object schema with required string property = const schema = Joi.object({ username: Joi.string().required() }); [OK]
Hint: Use Joi.object({ key: Joi.type().required() }) for required fields [OK]
Common Mistakes:
  • Defining schema as Joi.string() alone for object data
  • Using optional() instead of required()
  • Using wrong data type like Joi.number() for string
3. Given this Joi schema and data, what will schema.validate(data) return?
const schema = Joi.object({ age: Joi.number().min(18).required() });
const data = { age: 16 };
medium
A. Validation fails because age is less than 18
B. Validation passes with value { age: 16 }
C. Validation fails because age is missing
D. Validation passes with value { age: 18 }

Solution

  1. Step 1: Analyze schema rules for age

    Age must be a number, minimum 18, and required.
  2. Step 2: Check data against schema

    Data has age 16, which is less than minimum 18, so validation fails.
  3. Final Answer:

    Validation fails because age is less than 18 -> Option A
  4. Quick Check:

    Age < 18 fails min rule = Validation fails because age is less than 18 [OK]
Hint: Check min/max rules carefully when validating numbers [OK]
Common Mistakes:
  • Assuming 16 passes min(18) rule
  • Confusing missing field with invalid value
  • Thinking Joi changes value automatically
4. What is wrong with this Express route using Joi validation?
app.post('/user', (req, res) => {
  const schema = Joi.object({ email: Joi.string().email().required() });
  const result = schema.validate(req.body.email);
  if (result.error) {
    res.status(400).send('Invalid email');
  } else {
    res.send('User created');
  }
});
medium
A. It does not call next() after validation
B. It validates only the email string, not the whole object
C. It uses res.send instead of res.json
D. It should use Joi.number() for email

Solution

  1. Step 1: Check what is validated

    The schema expects an object with an email property, but code validates req.body.email (a string).
  2. Step 2: Understand Joi object validation

    To validate the whole object, pass req.body to schema.validate, not just one property.
  3. Final Answer:

    It validates only the email string, not the whole object -> Option B
  4. Quick Check:

    Validate whole object, not single property [OK]
Hint: Validate req.body object, not a single field string [OK]
Common Mistakes:
  • Validating only a property instead of full object
  • Confusing res.send and res.json (both work)
  • Forgetting to call next() is not required here
  • Using wrong Joi type for email
5. You want to validate a user object with optional phone that must be a string of 10 digits if present, and a required name string. Which Joi schema correctly enforces this?
hard
A. Joi.object({ name: Joi.string().required(), phone: Joi.string().pattern(/\d+/).required() })
B. Joi.object({ name: Joi.string(), phone: Joi.number().length(10).optional() })
C. Joi.object({ name: Joi.string().required(), phone: Joi.string().pattern(/^\d{10}$/).optional() })
D. Joi.object({ name: Joi.string().required(), phone: Joi.string().length(10).required() })

Solution

  1. Step 1: Identify required and optional fields

    Name is required string; phone is optional string matching exactly 10 digits.
  2. Step 2: Check regex pattern and optional usage

    Pattern /^\d{10}$/ matches exactly 10 digits; phone is optional, so use .optional().
  3. Step 3: Eliminate incorrect options

    Other options make phone required, use wrong types like Joi.number(), apply invalid methods like .length(10) on numbers, or use loose patterns like /\d+/.
  4. Final Answer:

    Joi.object({ name: Joi.string().required(), phone: Joi.string().pattern(/^\d{10}$/).optional() }) -> Option C
  5. Quick Check:

    Required name + optional 10-digit phone pattern = Joi.object({ name: Joi.string().required(), phone: Joi.string().pattern(/^\d{10}$/).optional() }) [OK]
Hint: Use .pattern(/^\d{10}$/) for exact 10-digit string [OK]
Common Mistakes:
  • Using Joi.number() for phone instead of string
  • Making optional field required
  • Using .length(10) on string without pattern
  • Using loose regex that allows wrong formats