Most Frequently asked Interview Questions of express
Question: What is req.body
in Express and how do you use it?
Answer:
In Express.js, req.body
is an object that contains data sent in the body of an HTTP request. It is typically used in POST, PUT, and PATCH requests, where data is sent by the client (e.g., via forms, JSON, or other types of request bodies) to the server.
1. What is req.body
?
req.body
is a property of the request object that holds the data sent in the body of the request.- It is used to access data sent by the client (browser, API client) when the client makes a POST, PUT, or PATCH request, where the data is typically not part of the URL but instead sent in the request body.
- This data can be in different formats, such as JSON, form data, or URL-encoded data.
2. How do you use req.body
in Express?
a. Setting up Middleware to Parse Request Body
To access req.body
, you must first use middleware to parse the incoming request body into a usable format. Express does not parse the body by default, so you need to tell it how to handle different types of data.
- For JSON data: Use
express.json()
middleware. - For URL-encoded data (e.g., from HTML forms): Use
express.urlencoded()
middleware.
Example Setup:
const express = require('express');
const app = express();
// Middleware to parse incoming JSON data
app.use(express.json());
// Middleware to parse URL-encoded form data
app.use(express.urlencoded({ extended: true }));
b. Accessing req.body
in Routes
Once the middleware is set up, you can access the request body inside your route handlers.
Example 1: Handling JSON Data
app.post('/user', (req, res) => {
const user = req.body; // Access the JSON data sent in the request body
console.log(user); // Log the user data to the console
res.send(`User created: ${JSON.stringify(user)}`);
});
- Example JSON Body (sent by client):
{ "name": "John Doe", "email": "[email protected]" }
- In the above example,
req.body
will contain the parsed JSON data, and you can directly access properties likereq.body.name
orreq.body.email
.
c. Handling URL-encoded Form Data
If the client sends data via an HTML form using the POST method (with the application/x-www-form-urlencoded
content type), you can access it in the same way as JSON data.
Example 2: Handling Form Data
app.post('/submit-form', (req, res) => {
const name = req.body.name; // Access the form data
const age = req.body.age;
res.send(`Received form data: Name - ${name}, Age - ${age}`);
});
- Example HTML Form:
<form action="/submit-form" method="POST"> <input type="text" name="name" placeholder="Your Name"> <input type="number" name="age" placeholder="Your Age"> <button type="submit">Submit</button> </form>
- In this example, when the form is submitted, the data is sent as URL-encoded form data, and
req.body.name
andreq.body.age
will contain the values entered in the form.
3. Common Use Cases for req.body
-
Creating or Updating Resources:
req.body
is most commonly used to send data to the server when creating or updating resources. For example, when a client submits a form to create a new user or update an existing user’s profile. -
Form Submissions: In web applications, forms often send data in the body of the request (as form data or JSON). For example, a login form or a contact form may send user input in the body to be processed by the server.
-
API Data: When building RESTful APIs,
req.body
is used to send JSON data from the client to the server, such as when creating new records in a database or updating existing records.
4. Example: Using req.body
for User Registration
app.post('/register', (req, res) => {
const { username, password } = req.body;
// Simulate saving the user to a database (just a mock example)
console.log(`User registered: ${username}, with password: ${password}`);
res.status(201).send(`User ${username} registered successfully`);
});
-
Example Request (using Postman or similar):
- URL:
http://localhost:3000/register
- Method:
POST
- Body (raw JSON):
{ "username": "john_doe", "password": "12345" }
Response:
User john_doe registered successfully
- URL:
5. Important Notes about req.body
-
Middleware Requirement: As mentioned earlier, Express does not automatically parse the body of requests. You must explicitly use middleware like
express.json()
orexpress.urlencoded()
to parse the request body. -
Content-Type: The content type of the request body must match the type that your middleware is set to parse. For example:
- If the client sends JSON, use
express.json()
. - If the client sends URL-encoded data (from a form), use
express.urlencoded()
.
- If the client sends JSON, use
-
Data Validation: It’s important to validate the data in
req.body
to ensure it meets your application’s requirements. For example, you can check if required fields are present or if the data is in the correct format (e.g., checking if an email is valid).
Summary:
req.body
in Express is used to access data sent in the body of HTTP requests (POST, PUT, PATCH).- You need to use middleware such as
express.json()
orexpress.urlencoded()
to parse the request body. - You can access
req.body
in your route handlers and perform operations like saving the data or sending a response. - It is most commonly used for handling form submissions, API requests, and creating or updating resources.
Question: What is next()
in Express.js middleware?
Answer:
In Express.js, next()
is a function that is used to pass control to the next middleware function in the request-response cycle. It is a core concept in how middleware works in Express, allowing the application to chain multiple middleware functions together to process requests in a structured manner.
1. What is Middleware in Express?
Middleware in Express is a function that has access to the request (req
), response (res
), and the next function. Middleware functions are used to perform tasks such as:
- Modifying the request or response objects
- Handling authentication or authorization
- Logging requests
- Parsing request bodies (e.g.,
express.json()
,express.urlencoded()
) - Handling errors
Middleware functions are executed sequentially in the order they are added in the application.
2. The Role of next()
in Middleware
The next()
function is crucial for the flow of control between middleware functions. When a middleware function has finished its task, it calls next()
to pass control to the next middleware function in the stack.
- If
next()
is called without any arguments, the request is passed on to the next middleware function. - If
next()
is called with an error as an argument, Express skips the remaining middleware functions and jumps to the error handling middleware.
3. Basic Example of next()
in Middleware
Here’s a simple example of how next()
works in Express middleware:
const express = require('express');
const app = express();
// First middleware
app.use((req, res, next) => {
console.log('First middleware');
next(); // Pass control to the next middleware
});
// Second middleware
app.use((req, res, next) => {
console.log('Second middleware');
res.send('Hello from second middleware'); // Response sent to client
// No need to call next() here, because the response is already sent
});
app.listen(3000, () => {
console.log('Server running on port 3000');
});
- Explanation:
- The first middleware logs
'First middleware'
and then callsnext()
to pass control to the second middleware. - The second middleware logs
'Second middleware'
and sends a response back to the client. - Because the response is sent in the second middleware, no further middleware is executed after that.
- The first middleware logs
4. Using next()
to Handle Errors
When an error occurs in a middleware function, it’s common to pass the error to the error handling middleware by calling next(err)
.
Example of error handling with next()
:
app.use((req, res, next) => {
const error = new Error('Something went wrong!');
next(error); // Pass the error to the next error-handling middleware
});
// Error-handling middleware
app.use((err, req, res, next) => {
console.error(err.message); // Log the error message
res.status(500).send('Internal Server Error');
});
- Explanation:
- The first middleware creates an error and passes it to the next middleware by calling
next(error)
. - The second middleware is an error-handling middleware. Express knows that it’s an error handler because it has four parameters (
err
,req
,res
,next
). When an error is passed tonext()
, this middleware catches it and sends an error response.
- The first middleware creates an error and passes it to the next middleware by calling
5. How next()
Helps with Routing
In route handlers, next()
can be used to pass control to the next middleware for the same route, allowing for modular handling of requests.
Example of multiple route-handling middleware:
app.get('/user', (req, res, next) => {
console.log('First middleware in /user route');
next(); // Pass control to the next middleware
});
app.get('/user', (req, res) => {
console.log('Second middleware in /user route');
res.send('User route handled');
});
- Explanation:
- The first middleware logs a message and passes control to the next middleware using
next()
. - The second middleware handles the request and sends a response back to the client.
- Both middlewares are used for the same route (
/user
).
- The first middleware logs a message and passes control to the next middleware using
6. Middleware with Conditional Logic and next()
You can use next()
conditionally to control the flow of your request-processing logic.
app.use((req, res, next) => {
if (req.query.admin === 'true') {
next(); // User is an admin, continue to the next middleware
} else {
res.status(403).send('Forbidden'); // Non-admin users are forbidden
}
});
app.use((req, res) => {
res.send('Welcome, Admin!');
});
- Explanation:
- The first middleware checks if the
admin
query parameter istrue
. If it is, it callsnext()
to pass control to the next middleware. - If the query parameter is not
true
, it sends a403 Forbidden
response without callingnext()
. - The second middleware handles the request if the first middleware calls
next()
.
- The first middleware checks if the
7. Using next()
in Asynchronous Code
Since middleware functions can be asynchronous (e.g., for database queries or I/O operations), next()
can be used after asynchronous operations are completed.
app.use((req, res, next) => {
setTimeout(() => {
console.log('Asynchronous middleware finished');
next(); // Call next() after the asynchronous operation
}, 2000); // Simulate an async operation (e.g., a database query)
});
- Explanation:
- The middleware simulates an asynchronous operation (using
setTimeout
) and callsnext()
once the operation is finished, allowing the next middleware to run.
- The middleware simulates an asynchronous operation (using
Summary:
next()
is a function used in Express.js middleware to pass control to the next middleware function in the request-response cycle.- It ensures that the request is processed through multiple middlewares in a specific order.
- If an error occurs in a middleware,
next(error)
passes control to error-handling middleware. - It can also be used conditionally to control the flow of request processing based on logic, such as authentication or validation.
Question: What are template engines in Express.js, and which ones are commonly used?
Answer:
In Express.js, template engines are used to dynamically generate HTML pages by embedding data into templates. They enable you to define templates that contain placeholders, which are then filled with data from your application (like user input, database results, or other dynamic content). Template engines in Express help separate the presentation logic from the application logic, making your code cleaner and easier to maintain.
Template engines typically allow you to:
- Embed JavaScript logic within HTML (like loops, conditionals, etc.).
- Use variables in your HTML to display dynamic data.
- Generate HTML dynamically on the server before sending it to the client.
1. How Template Engines Work in Express.js
When you use a template engine in an Express application, you can define a view (or template) and then render that view with dynamic data. The render() function is used to generate the final HTML, and the result is sent to the client.
Example:
app.set('view engine', 'ejs'); // Set the template engine to EJS
app.get('/', (req, res) => {
res.render('index', { title: 'Hello, Express!' }); // Render the 'index' template with data
});
In this example, EJS (a template engine) is used to render an HTML page with a dynamic title passed via res.render()
. The EJS template will use that data to display the title.
2. Common Template Engines Used in Express.js
Here are some of the most commonly used template engines in Express.js:
a. EJS (Embedded JavaScript)
- EJS is one of the most popular and widely used template engines in Express.js. It allows you to embed JavaScript directly into your HTML templates using
<% %>
tags.
Features:
- Simple syntax similar to standard HTML.
- Supports embedded JavaScript for loops, conditionals, and expressions.
- Provides partial views for reusable components (like headers, footers).
Example:
app.set('view engine', 'ejs'); // Set EJS as the template engine
app.get('/', (req, res) => {
res.render('index', { title: 'Welcome to Express' });
});
index.ejs:
<html>
<head>
<title><%= title %></title>
</head>
<body>
<h1><%= title %></h1>
</body>
</html>
b. Pug (formerly Jade)
- Pug (formerly known as Jade) is another popular template engine for Express. Pug uses a more concise, indentation-based syntax, making the templates more readable and less verbose.
Features:
- Clean, minimalistic syntax (no need for closing tags).
- Supports features like mixins, conditionals, loops, and includes.
- Better suited for larger templates with a focus on readability and maintainability.
Example:
app.set('view engine', 'pug'); // Set Pug as the template engine
app.get('/', (req, res) => {
res.render('index', { title: 'Welcome to Express' });
});
index.pug:
doctype html
html
head
title= title
body
h1= title
c. Handlebars
- Handlebars is a template engine that offers a logic-less syntax, making it easy to create templates with minimal logic. It is often used in web applications that need to separate the template structure from the logic.
Features:
- Simple syntax with
{{ }}
placeholders. - Supports helpers for reusable logic.
- Logic-less templates (keeps business logic out of the template).
Example:
const exphbs = require('express-handlebars');
app.engine('handlebars', exphbs()); // Set Handlebars as the template engine
app.set('view engine', 'handlebars');
app.get('/', (req, res) => {
res.render('home', { title: 'Welcome to Express' });
});
home.handlebars:
<html>
<head>
<title>{{title}}</title>
</head>
<body>
<h1>{{title}}</h1>
</body>
</html>
d. Mustache
- Mustache is a simple and lightweight template engine that uses the
{{ }}
syntax similar to Handlebars but with fewer features. It’s called “logic-less” because it does not support conditions or loops directly in the template, which makes it easier to maintain.
Features:
- Minimalistic, logic-less syntax.
- Used when you want a very basic template engine without complex logic.
- Often used in smaller applications or when simplicity is important.
Example:
const mustacheExpress = require('mustache-express');
app.engine('mustache', mustacheExpress()); // Set Mustache as the template engine
app.set('view engine', 'mustache');
app.get('/', (req, res) => {
res.render('home', { title: 'Welcome to Express' });
});
home.mustache:
<html>
<head>
<title>{{title}}</title>
</head>
<body>
<h1>{{title}}</h1>
</body>
</html>
e. Nunjucks
- Nunjucks is a feature-rich template engine inspired by Jinja2 (from Python). It provides powerful features like inheritance, macros, filters, and more, making it suitable for both simple and complex applications.
Features:
- Extensible with filters, macros, and extensions.
- Supports template inheritance, making it easier to work with layouts.
- Designed for more advanced use cases.
Example:
const nunjucks = require('nunjucks');
app.set('view engine', 'njk'); // Set Nunjucks as the template engine
app.set('views', path.join(__dirname, 'views'));
app.get('/', (req, res) => {
res.render('home', { title: 'Welcome to Express' });
});
home.njk:
<html>
<head>
<title>{{ title }}</title>
</head>
<body>
<h1>{{ title }}</h1>
</body>
</html>
3. How to Set a Template Engine in Express
To use a template engine in Express, you typically set the view engine
property to the name of the engine you’re using. For example, if you’re using EJS:
app.set('view engine', 'ejs');
Then, you can use res.render()
to render a template and pass data to it.
4. Which Template Engine Should You Choose?
The choice of template engine depends on your project needs:
- EJS: Great for developers familiar with HTML and JavaScript. It’s simple and flexible.
- Pug: Ideal for developers who prefer concise, clean syntax with indentation-based markup.
- Handlebars/Mustache: Good for keeping templates simple and logic-less, and if you need reusable helpers.
- Nunjucks: Suitable for more complex applications requiring powerful features like template inheritance and macros.
Summary:
- Template engines in Express allow you to generate dynamic HTML pages by embedding data into templates.
- Common template engines used in Express include EJS, Pug, Handlebars, Mustache, and Nunjucks.
- Template engines provide a way to separate application logic from presentation logic, improving maintainability and scalability of applications.
Question: How do you set up a static file server in Express.js?
Answer:
In Express.js, you can serve static files (such as images, CSS, JavaScript, or any other publicly accessible files) by using the built-in express.static()
middleware. This middleware serves files from a specific directory, making them available to the client without requiring additional processing from the server.
1. Setting Up a Static File Server in Express
To serve static files, you need to specify the directory where these files are located. The express.static()
middleware takes the path to the directory where the static files are stored and makes them accessible via a URL path.
Example Setup:
const express = require('express');
const path = require('path');
const app = express();
// Serve static files from the 'public' directory
app.use(express.static(path.join(__dirname, 'public')));
app.get('/', (req, res) => {
res.send('Welcome to the static file server!');
});
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
Explanation:
express.static(path)
: This middleware tells Express to serve static files from the specified directory ('public'
in this case). All files inside thepublic
directory will be accessible via the server.path.join(__dirname, 'public')
: This ensures the correct path is used to find thepublic
directory, regardless of the operating system (since file paths differ between Windows and Linux).- In this example, if there’s a file like
public/images/logo.png
, it will be accessible athttp://localhost:3000/images/logo.png
.
2. Organizing Static Files
You can organize your static files in various subdirectories (e.g., images, stylesheets, JavaScript) within the static directory. For example:
/public
/images
logo.png
/styles
main.css
/scripts
app.js
This way, you can access the files like this:
http://localhost:3000/images/logo.png
http://localhost:3000/styles/main.css
http://localhost:3000/scripts/app.js
3. Serving Static Files from a Different URL Path
You can also serve static files under a different URL path by specifying a second argument in the express.static()
middleware. This allows you to map a virtual path to the static file directory.
Example:
app.use('/static', express.static(path.join(__dirname, 'public')));
With this setup, instead of accessing the static files directly from the root, you would need to prefix the URL with /static
. For example:
http://localhost:3000/static/images/logo.png
http://localhost:3000/static/styles/main.css
4. Serving Multiple Static Directories
If you need to serve files from multiple directories, you can use multiple express.static()
middleware calls.
Example:
app.use('/images', express.static(path.join(__dirname, 'public/images')));
app.use('/styles', express.static(path.join(__dirname, 'public/styles')));
With this setup:
- Files in the
public/images
directory will be accessible via/images
. - Files in the
public/styles
directory will be accessible via/styles
.
5. Serving Static Files with Caching
By default, Express provides caching for static files with the Cache-Control
header. You can customize the caching behavior using options.
Example: Setting Cache Expiry for Static Files
app.use(express.static(path.join(__dirname, 'public'), {
maxAge: '1d' // Cache static files for 1 day
}));
maxAge
: Specifies the maximum time (in ms, or using a string like'1d'
for 1 day) that static files should be cached by the browser.
6. Handling Errors for Missing Static Files
If a static file is requested but doesn’t exist, Express will automatically return a 404 Not Found
error. You can handle this error with custom error handling middleware.
Example:
app.use((req, res, next) => {
res.status(404).send('Sorry, we couldn’t find that file!');
});
This middleware will catch all unmatched routes and return a custom error message when a file is not found.
Summary:
- Use
express.static()
to serve static files in Express. - You can specify a directory (like
public
) and make files within it accessible via URLs. - You can serve static files from a different URL path using the second argument of
express.static()
. - Static files can be cached by setting the
maxAge
option to control cache duration. - You can serve files from multiple directories by calling
express.static()
multiple times with different paths.
This allows you to easily serve static assets like images, stylesheets, and JavaScript in your Express application.
Read More
If you can’t get enough from this article, Aihirely has plenty more related information, such as express interview questions, express interview experiences, and details about various express job positions. Click here to check it out.