Node.js API Validation Practice Questions with Solutions

Introduction

API validation checks whether data received by a Node.js API is present, correctly formatted, and safe to process. Good validation prevents invalid requests from reaching business logic or the database. In this chapter, you will practice API validation step by step, starting with required fields and data types, then moving to strings, numbers, email addresses, passwords, arrays, custom validation, middleware, and complete Express.js API validation. Node.js API Validation practice questions with solutions help to understand the concepts.

Question 1: How do you check required fields in a Node.js API?

Problem

Create an Express.js API that accepts a user’s name and email. Return an error if either field is missing.

Solution

const express = require("express");

const app = express();

app.use(express.json());

app.post("/users", (req, res) => {

    const {
        name,
        email
    } = req.body;

    if (!name || !email) {

        return res.status(400).json({

            success: false,

            message:
                "Name and email are required."

        });

    }

    res.status(201).json({

        success: true,

        message:
            "User data is valid.",

        user: {
            name,
            email
        }

    });

});

app.listen(3000, () => {

    console.log(
        "Server running on port 3000"
    );

});

Test Request

Send:

POST http://localhost:3000/users

JSON body:

{
    "name": "Rahul",
    "email": "rahul@example.com"
}

Response

{
    "success": true,
    "message": "User data is valid.",
    "user": {
        "name": "Rahul",
        "email": "rahul@example.com"
    }
}

Invalid Request

{
    "name": "Rahul"
}

Response:

{
    "success": false,
    "message": "Name and email are required."
}

Step-by-Step Explanation

First, get the values:

const {
    name,
    email
} = req.body;

Then check whether they exist:

if (!name || !email) {
    ...
}

If a required value is missing, return HTTP status 400.

Important Point

Validation should happen before your application attempts to save or process invalid data.


Question 2: How do you validate the data type of API fields?

Problem

Create an API that accepts:

  • name as a string
  • age as a number

Reject the request if the data types are incorrect.

Solution

const express = require("express");

const app = express();

app.use(express.json());

app.post("/users", (req, res) => {

    const {
        name,
        age
    } = req.body;

    if (
        typeof name !== "string"
    ) {

        return res.status(400).json({

            success: false,

            message:
                "Name must be a string."

        });

    }

    if (
        typeof age !== "number"
    ) {

        return res.status(400).json({

            success: false,

            message:
                "Age must be a number."

        });

    }

    res.json({

        success: true,

        message:
            "Data validation successful.",

        user: {
            name,
            age
        }

    });

});

app.listen(3000, () => {

    console.log(
        "Server running on port 3000"
    );

});

Valid Request

{
    "name": "Rahul",
    "age": 20
}

Invalid Request

{
    "name": 100,
    "age": "20"
}

Response:

{
    "success": false,
    "message": "Name must be a string."
}

Step-by-Step Explanation

JavaScript provides typeof to check the type of a value.

For example:

typeof "Rahul"

returns:

string

And:

typeof 20

returns:

number

Therefore:

typeof name !== "string"

means the name is not a string.

Important Point

A value such as "20" is a string, not a number:

typeof "20"

returns:

string

while:

typeof 20

returns:

number

Question 3: How do you validate string length in a Node.js API?

Problem

Create an API where the username must contain between 3 and 20 characters.

Solution

const express = require("express");

const app = express();

app.use(express.json());

app.post("/register", (req, res) => {

    const {
        username
    } = req.body;

    if (
        typeof username !== "string"
    ) {

        return res.status(400).json({

            message:
                "Username must be a string."

        });

    }

    if (
        username.length < 3 ||
        username.length > 20
    ) {

        return res.status(400).json({

            message:
                "Username must contain 3 to 20 characters."

        });

    }

    res.json({

        success: true,

        message:
            "Username is valid."

    });

});

app.listen(3000, () => {

    console.log(
        "Server running on port 3000"
    );

});

Valid Request

{
    "username": "rahul123"
}

Invalid Request

{
    "username": "ab"
}

Response:

{
    "message": "Username must contain 3 to 20 characters."
}

Step-by-Step Explanation

The length property tells us how many characters are in the string.

username.length

For example:

"Rahul".length

returns:

5

We check both limits:

username.length &lt; 3 ||
username.length > 20

Important Point

It is usually a good idea to remove accidental spaces before validating user-entered strings:

const username =
    usernameInput.trim();

Question 4: How do you validate an email address in a Node.js API?

Problem

Create an API that checks whether the user has provided an email in a basic valid format.

Solution

const express = require("express");

const app = express();

app.use(express.json());

app.post("/register", (req, res) => {

    const {
        email
    } = req.body;

    if (
        typeof email !== "string"
    ) {

        return res.status(400).json({

            message:
                "Email must be a string."

        });

    }

    const emailPattern =
        /^[^\s@]+@[^\s@]+\.[^\s@]+$/;

    if (
        !emailPattern.test(email)
    ) {

        return res.status(400).json({

            message:
                "Please provide a valid email address."

        });

    }

    res.json({

        success: true,

        message:
            "Email is valid."

    });

});

app.listen(3000, () => {

    console.log(
        "Server running on port 3000"
    );

});

Valid Request

{
    "email": "rahul@example.com"
}

Invalid Request

{
    "email": "rahul@example"
}

Step-by-Step Explanation

The regular expression is:

const emailPattern =
    /^[^\s@]+@[^\s@]+\.[^\s@]+$/;

We test the email:

emailPattern.test(email)

If the result is false, the email does not match the expected basic format.

Important Point

Email validation can become complex. A simple regular expression is useful for basic input validation, but it does not prove that an email address actually exists.


Question 5: How do you validate a password in a Node.js API?

Problem

Create a registration API where the password must:

  • Be a string
  • Contain at least 8 characters
  • Contain at least one number

Solution

const express = require("express");

const app = express();

app.use(express.json());

app.post("/register", (req, res) => {

    const {
        password
    } = req.body;

    if (
        typeof password !== "string"
    ) {

        return res.status(400).json({

            message:
                "Password must be a string."

        });

    }

    if (
        password.length < 8
    ) {

        return res.status(400).json({

            message:
                "Password must contain at least 8 characters."

        });

    }

    if (
        !/\d/.test(password)
    ) {

        return res.status(400).json({

            message:
                "Password must contain at least one number."

        });

    }

    res.json({

        success: true,

        message:
            "Password validation successful."

    });

});

app.listen(3000, () => {

    console.log(
        "Server running on port 3000"
    );

});

Valid Password

Rahul123

Invalid Password

Rahul

The password is rejected because it has fewer than 8 characters.

Another Invalid Password

RahulKumar

It is rejected because it contains no number.

Step-by-Step Explanation

Check the type:

typeof password !== "string"

Check the length:

password.length < 8

Check for a number:

/\d/.test(password)

The \d pattern looks for a digit.

Important Point

Validation only checks whether a password meets your input rules. It does not protect a stored password. Passwords should be hashed before being stored in a database.


Question 6: How do you validate numbers and number ranges?

Problem

Create an API that accepts a user’s age and allows only values between 13 and 100.

Solution

const express = require("express");

const app = express();

app.use(express.json());

app.post("/users", (req, res) => {

    const {
        age
    } = req.body;

    if (
        typeof age !== "number" ||
        !Number.isFinite(age)
    ) {

        return res.status(400).json({

            message:
                "Age must be a valid number."

        });

    }

    if (
        age < 13 ||
        age > 100
    ) {

        return res.status(400).json({

            message:
                "Age must be between 13 and 100."

        });

    }

    res.json({

        success: true,

        message:
            "Age is valid.",

        age: age

    });

});

app.listen(3000, () => {

    console.log(
        "Server running on port 3000"
    );

});

Valid Request

{
    "age": 20
}

Invalid Request

{
    "age": 10
}

Response:

{
    "message": "Age must be between 13 and 100."
}

Another Invalid Request

{
    "age": "20"
}

This is rejected because "20" is a string.

Step-by-Step Explanation

First check the type:

typeof age !== "number"

Then check that the value is a finite number:

Number.isFinite(age)

Finally check the allowed range:

age < 13 ||
age > 100

Important Point

Do not assume that data received from a client has the correct type. Always validate it before using it.


Question 7: How do you validate arrays in a Node.js API?

Problem

Create an API that accepts a list of skills. The API should require:

  • skills to be an array
  • At least one skill
  • Each skill to be a string

Solution

const express = require("express");

const app = express();

app.use(express.json());

app.post("/profile", (req, res) => {

    const {
        skills
    } = req.body;

    if (
        !Array.isArray(skills)
    ) {

        return res.status(400).json({

            message:
                "Skills must be an array."

        });

    }

    if (
        skills.length === 0
    ) {

        return res.status(400).json({

            message:
                "At least one skill is required."

        });

    }

    const allStrings =
        skills.every(
            skill =>
                typeof skill === "string"
        );

    if (!allStrings) {

        return res.status(400).json({

            message:
                "Every skill must be a string."

        });

    }

    res.json({

        success: true,

        message:
            "Skills are valid.",

        skills:
            skills

    });

});

app.listen(3000, () => {

    console.log(
        "Server running on port 3000"
    );

});

Valid Request

{
    "skills": [
        "Node.js",
        "JavaScript",
        "MongoDB"
    ]
}

Invalid Request

{
    "skills": []
}

Response:

{
    "message": "At least one skill is required."
}

Another Invalid Request

{
    "skills": [
        "Node.js",
        100
    ]
}

Response:

{
    "message": "Every skill must be a string."
}

Step-by-Step Explanation

Check whether it is an array:

Array.isArray(skills)

Check whether it contains values:

skills.length === 0

Check every item:

skills.every(
    skill =>
        typeof skill === "string"
)

Important Point

Array validation is useful when an API accepts lists such as skills, tags, product IDs, categories, or permissions.


Question 8: How do you create reusable validation middleware?

Problem

Create middleware that validates name and email before the request reaches the API route.

Solution

const express = require("express");

const app = express();

app.use(express.json());


function validateUser(
    req,
    res,
    next
) {

    const {
        name,
        email
    } = req.body;

    if (
        typeof name !== "string" ||
        name.trim() === ""
    ) {

        return res.status(400).json({

            message:
                "Name is required."

        });

    }

    if (
        typeof email !== "string"
    ) {

        return res.status(400).json({

            message:
                "Email is required."

        });

    }

    const emailPattern =
        /^[^\s@]+@[^\s@]+\.[^\s@]+$/;

    if (
        !emailPattern.test(email)
    ) {

        return res.status(400).json({

            message:
                "Invalid email address."

        });

    }

    next();

}


app.post(
    "/users",
    validateUser,
    (req, res) => {

        res.status(201).json({

            success: true,

            message:
                "User data passed validation.",

            user:
                req.body

        });

    }
);


app.listen(3000, () => {

    console.log(
        "Server running on port 3000"
    );

});

Step-by-Step Explanation

The request first enters:

validateUser

The middleware checks the data.

If validation fails, it sends a response:

return res.status(400).json({
    ...
});

If validation succeeds:

next();

The request then reaches the route:

(req, res) => {
    ...
}

Request Flow

Client
  ↓
POST /users
  ↓
validateUser()
  ↓
Valid?
 ↙     ↘
No      Yes
↓        ↓
400    next()
         ↓
      Route
         ↓
      Response

Question 9: How do you validate multiple API fields and return all validation errors?

Problem

Create an API that validates:

  • Name
  • Email
  • Age
  • Password

Instead of returning only the first error, return all validation errors together.

Solution

const express = require("express");

const app = express();

app.use(express.json());

app.post("/register", (req, res) => {

    const {
        name,
        email,
        age,
        password
    } = req.body;

    const errors = [];


    // Name validation

    if (
        typeof name !== "string" ||
        name.trim() === ""
    ) {

        errors.push(
            "Name is required."
        );

    }


    // Email validation

    if (
        typeof email !== "string"
    ) {

        errors.push(
            "Email is required."
        );

    } else {

        const emailPattern =
            /^[^\s@]+@[^\s@]+\.[^\s@]+$/;

        if (
            !emailPattern.test(email)
        ) {

            errors.push(
                "Email format is invalid."
            );

        }

    }


    // Age validation

    if (
        typeof age !== "number" ||
        !Number.isFinite(age)
    ) {

        errors.push(
            "Age must be a valid number."
        );

    } else if (
        age < 13 ||
        age > 100
    ) {

        errors.push(
            "Age must be between 13 and 100."
        );

    }


    // Password validation

    if (
        typeof password !== "string"
    ) {

        errors.push(
            "Password is required."
        );

    } else if (
        password.length < 8
    ) {

        errors.push(
            "Password must contain at least 8 characters."
        );

    }


    // Return errors

    if (
        errors.length > 0
    ) {

        return res.status(400).json({

            success: false,

            errors:
                errors

        });

    }


    res.status(201).json({

        success: true,

        message:
            "Registration data is valid."

    });

});


app.listen(3000, () => {

    console.log(
        "Server running on port 3000"
    );

});

Invalid Request

{
    "name": "",
    "email": "wrong-email",
    "age": 10,
    "password": "abc"
}

Response

{
    "success": false,
    "errors": [
        "Name is required.",
        "Email format is invalid.",
        "Age must be between 13 and 100.",
        "Password must contain at least 8 characters."
    ]
}

Step-by-Step Explanation

Create an empty array:

const errors = [];

Whenever validation fails, add an error:

errors.push(
    "Name is required."
);

At the end:

if (errors.length > 0)

checks whether any validation errors were collected.

Important Point

Returning multiple validation errors can make APIs easier for frontend developers to work with because they can display all relevant problems at once.


Question 10: How do you validate a complete Express.js registration API?

Problem

Build a complete registration API that validates:

  • Name
  • Email
  • Age
  • Password
  • Skills

Use reusable validation middleware and return clear error messages.

Solution

const express = require("express");

const app = express();

app.use(express.json());


function validateRegistration(
    req,
    res,
    next
) {

    const {
        name,
        email,
        age,
        password,
        skills
    } = req.body;

    const errors = [];


    // Name

    if (
        typeof name !== "string" ||
        name.trim() === ""
    ) {

        errors.push(
            "Name is required."
        );

    } else if (
        name.trim().length < 3
    ) {

        errors.push(
            "Name must contain at least 3 characters."
        );

    }


    // Email

    if (
        typeof email !== "string"
    ) {

        errors.push(
            "Email is required."
        );

    } else {

        const emailPattern =
            /^[^\s@]+@[^\s@]+\.[^\s@]+$/;

        if (
            !emailPattern.test(email)
        ) {

            errors.push(
                "Please provide a valid email address."
            );

        }

    }


    // Age

    if (
        typeof age !== "number" ||
        !Number.isFinite(age)
    ) {

        errors.push(
            "Age must be a valid number."
        );

    } else if (
        age < 13 ||
        age > 100
    ) {

        errors.push(
            "Age must be between 13 and 100."
        );

    }


    // Password

    if (
        typeof password !== "string"
    ) {

        errors.push(
            "Password is required."
        );

    } else {

        if (
            password.length < 8
        ) {

            errors.push(
                "Password must contain at least 8 characters."
            );

        }

        if (
            !/\d/.test(password)
        ) {

            errors.push(
                "Password must contain at least one number."
            );

        }

    }


    // Skills

    if (
        !Array.isArray(skills)
    ) {

        errors.push(
            "Skills must be an array."
        );

    } else {

        if (
            skills.length === 0
        ) {

            errors.push(
                "At least one skill is required."
            );

        }

        const validSkills =
            skills.every(
                skill =>
                    typeof skill === "string" &&
                    skill.trim() !== ""
            );

        if (!validSkills) {

            errors.push(
                "Every skill must be a non-empty string."
            );

        }

    }


    // Return errors

    if (
        errors.length > 0
    ) {

        return res.status(400).json({

            success: false,

            errors:
                errors

        });

    }


    next();

}


app.post(
    "/register",
    validateRegistration,
    (req, res) => {

        const {
            name,
            email,
            age,
            skills
        } = req.body;

        res.status(201).json({

            success: true,

            message:
                "Registration data is valid.",

            user: {

                name:
                    name.trim(),

                email:
                    email.trim(),

                age:
                    age,

                skills:
                    skills

            }

        });

    }
);


app.listen(3000, () => {

    console.log(
        "Server running on port 3000"
    );

});

Valid Request

{
    "name": "Rahul Kumar",
    "email": "rahul@example.com",
    "age": 20,
    "password": "Rahul12345",
    "skills": [
        "Node.js",
        "JavaScript",
        "MongoDB"
    ]
}

Response

{
    "success": true,
    "message": "Registration data is valid.",
    "user": {
        "name": "Rahul Kumar",
        "email": "rahul@example.com",
        "age": 20,
        "skills": [
            "Node.js",
            "JavaScript",
            "MongoDB"
        ]
    }
}

Invalid Request

{
    "name": "Ra",
    "email": "wrong",
    "age": 10,
    "password": "abc",
    "skills": []
}

Response

{
    "success": false,
    "errors": [
        "Name must contain at least 3 characters.",
        "Please provide a valid email address.",
        "Age must be between 13 and 100.",
        "Password must contain at least 8 characters.",
        "Password must contain at least one number.",
        "At least one skill is required."
    ]
}

Step-by-Step Explanation

The API receives JSON data:

req.body

The validation middleware checks every field.

If errors exist:

if (errors.length > 0)

the API returns:

400 Bad Request

If everything is valid:

next();

passes control to the registration route.

Complete Flow

Client
  ↓
POST /register
  ↓
Receive JSON
  ↓
Validate Name
  ↓
Validate Email
  ↓
Validate Age
  ↓
Validate Password
  ↓
Validate Skills
  ↓
Any Errors?
 ↙          ↘
Yes          No
 ↓            ↓
400         next()
 ↓            ↓
Errors     API Route
              ↓
          Process Data
              ↓
           Response

Important Point

Validation should be performed on the server even if the frontend already validates the same data. Client-side validation improves user experience, but server-side validation is necessary because clients cannot be trusted.

Key Takeaways

1. API validation checks incoming data

Validation confirms that client-provided data meets the application’s requirements before it is processed.

2. req.body contains JSON request data

With Express JSON middleware:

app.use(express.json());

you can access JSON data through:

req.body

3. Required fields should be checked

For example:

if (!name) {
    // validation error
}

4. Check data types

Use:

typeof value

to check primitive data types.

5. Use Array.isArray() for arrays

Example:

Array.isArray(skills)

6. Validate string length

Use:

username.length

to check the number of characters.

7. Validate number ranges

For example:

if (age < 13 || age > 100) {
    // invalid
}

8. Validate email format

A basic regular expression can check the general structure of an email address.

9. Validate passwords before processing them

Password rules may include minimum length and character requirements.

10. Never store plain-text passwords

Validation does not replace password hashing. Passwords should be securely hashed before storage.

11. Use middleware for reusable validation

Validation middleware can be shared by multiple routes.

12. next() continues the request

When validation succeeds:

next();

passes control to the next middleware or route handler.

13. HTTP 400 is commonly used for invalid request data

A malformed or invalid client request can commonly result in:

400 Bad Request

14. Return clear validation errors

Instead of returning only:

Invalid data

give the client useful information about what needs to be corrected.

15. Multiple errors can be returned together

An errors array is a simple way to return several validation problems.

16. Validate before database operations

Do not send obviously invalid data directly to MongoDB or another database.

17. Client-side validation is not enough

A malicious or modified client can bypass frontend validation. The server must validate its own input.

18. Validation and sanitization are different

Validation asks:

Is this data acceptable?

Sanitization asks:

Can this data be safely normalized or cleaned?

Both can be useful depending on the application.

19. Do not trust client-provided data

Everything received from an API client should be treated as untrusted input until validated.

20. Production APIs often use validation libraries

For larger applications, libraries such as Joi, Zod, or express-validator can reduce repetitive validation code and provide structured schemas.

FAQs

1. What is API validation in Node.js?

API validation is the process of checking incoming API data before the application processes it.

For example, an API may check whether:

  • A name exists
  • An email has a valid format
  • An age is a number
  • A password meets minimum requirements

2. Why is API validation important in Node.js?

API validation helps prevent invalid or unexpected data from reaching application logic and databases.

It also gives API clients clear information about what went wrong with their request.

3. How do I validate required fields in Express.js?

You can check whether the values exist:

if (!name || !email) {

    return res.status(400).json({

        message:
            "Name and email are required."

    });

}

If a required field is missing, the API can return a 400 Bad Request response.

4. How do I validate an email in Node.js?

You can use a regular expression for basic format validation:

const emailPattern =
    /^[^\s@]+@[^\s@]+\.[^\s@]+$/;

if (!emailPattern.test(email)) {

    return res.status(400).json({

        message:
            "Invalid email address."

    });

}

For production applications, a dedicated validation library can provide more structured validation.

5. What status code should I use for invalid API input?

400 Bad Request is commonly used when the request contains invalid input.

For example:

res.status(400).json({
    message: "Invalid email."
});

The exact status code should match the API’s semantics and error-handling conventions.

6. Should I validate data before saving it to MongoDB?

Yes. Server-side validation should happen before storing client-provided data in MongoDB.

For example:

Request
  ↓
Validation
  ↓
Valid?
  ↓
Database

Do not rely only on frontend validation or database validation.

7. Is Express.js enough for API validation?

Express.js provides the request and middleware structure needed to implement validation, but it does not provide a complete schema-validation system by itself.

For larger projects, you can use libraries such as Joi, Zod, or express-validator to create reusable validation schemas and rules.

Written by Shubhranshu Shekhar, who has trained 20000+ students in coding.

Scroll to Top