Express.js is a minimal and flexible Node.js web application framework that provides a robust set of features to develop web and mobile applications. It simplifies the process of handling requests and responses, which are fundamental components of any web application. In this chapter, we will explore the intricacies of request and response handling in Express.js, starting from the basics and moving towards advanced concepts.
A request in Express.js represents the HTTP request made by a client to your server. It contains information about the request method, URL, headers, and body.
The request
object (req
) in Express.js contains several properties that provide information about the incoming request.
app.get('/', (req, res) => {
console.log(req.method); // GET
console.log(req.url); // /
console.log(req.headers); // {host: 'localhost:3000', ...}
res.send('Hello World');
});
req
req.method
: The HTTP method of the request (e.g., GET, POST).req.url
: The URL of the request.req.headers
: An object containing the headers of the request.req.query
: An object containing query string parameters.req.params
: An object containing URL parameters.req.body
: An object containing data sent in the request body (requires middleware to parse).Express provides methods corresponding to different HTTP methods: get
, post
, put
, delete
, etc.
app.get('/get', (req, res) => {
res.send('GET request received');
});
app.post('/post', (req, res) => {
res.send('POST request received');
});
app.put('/put', (req, res) => {
res.send('PUT request received');
});
app.delete('/delete', (req, res) => {
res.send('DELETE request received');
});
Query parameters are sent in the URL after the ?
symbol.
app.get('/search', (req, res) => {
const { q } = req.query;
res.send(`Search query: ${q}`);
});
URL parameters are defined in the route path and accessed using req.params
.
app.get('/user/:id', (req, res) => {
const { id } = req.params;
res.send(`User ID: ${id}`);
});
Visit http://localhost:3000/user/123
to see the output.
To handle body data, you need middleware to parse it. For JSON data, use express.json()
:
app.use(express.json());
app.post('/data', (req, res) => {
const { name, age } = req.body;
res.send(`Name: ${name}, Age: ${age}`);
});
Use Postman or a similar tool to send a POST request with a JSON body to http://localhost:3000/data
.
A response in Express.js represents the HTTP response sent by your server to the client. The response
object (res
) contains methods to customize the response.
The res
object has several methods to send different types of responses, set headers, and status codes.
Sending Text
app.get('/text', (req, res) => {
res.send('This is a plain text response');
});
Sending JSON
app.get('/json', (req, res) => {
res.json({ message: 'This is a JSON response' });
});
Sending Files
app.get('/file', (req, res) => {
res.sendFile(__dirname + '/path/to/file');
});
Setting Headers
app.get('/header', (req, res) => {
res.set('Custom-Header', 'HeaderValue');
res.send('Header set');
});
Setting Status Codes
app.get('/status', (req, res) => {
res.status(404).send('Not Found');
});
Middleware functions are functions that have access to the req
and res
objects and can modify them or terminate the request-response cycle.
app.use((req, res, next) => {
console.log('Middleware function executed');
next(); // Pass control to the next middleware
});
app.get('/', (req, res) => {
res.send('Hello World with Middleware');
});
Error handling middleware is used to catch and respond to errors that occur in the application.
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).send('Something broke!');
});
app.get('/error', (req, res) => {
throw new Error('BROKEN'); // Express will catch this on its own.
});
Let’s build a simple blog API with Express.js that allows users to create, read, update, and delete blog posts. This practical example will cover request and response handling, including parsing request bodies, setting response headers and status codes, and handling errors.
Create a new project directory and initialize a Node.js project:
mkdir blog-api
cd blog-api
npm init -y
Install the necessary packages:
npm install express
npm install body-parser
Create an index.js
file for your Express server.
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
const port = 3000;
// Middleware to parse JSON bodies
app.use(bodyParser.json());
let posts = [];
// Routes
app.get('/', (req, res) => {
res.send('Welcome to the Blog API');
});
// Start the server
app.listen(port, () => {
console.log(`Server is running on http://localhost:${port}`);
});
app.post('/posts', (req, res) => {
const { title, content } = req.body;
const newPost = { id: posts.length + 1, title, content };
posts.push(newPost);
res.status(201).json(newPost);
});
app.post()
to handle POST requests to the /posts
endpoint.body-parser
middleware.posts
array.201 Created
status code is sent along with the newly created post.
app.get('/posts', (req, res) => {
res.json(posts);
});
app.get()
to handle GET requests to the /posts
endpoint.posts
array is sent as a JSON response.
app.get('/posts/:id', (req, res) => {
const postId = parseInt(req.params.id, 10);
const post = posts.find(p => p.id === postId);
if (post) {
res.json(post);
} else {
res.status(404).send('Post not found');
}
});
app.get()
to handle GET requests to /posts/:id
, where :id
is a URL parameter.posts
array.404 Not Found
status code is sent.
app.put('/posts/:id', (req, res) => {
const postId = parseInt(req.params.id, 10);
const { title, content } = req.body;
const postIndex = posts.findIndex(p => p.id === postId);
if (postIndex !== -1) {
posts[postIndex] = { id: postId, title, content };
res.json(posts[postIndex]);
} else {
res.status(404).send('Post not found');
}
});
app.put()
to handle PUT requests to /posts/:id
.404 Not Found
status code is sent.
app.delete('/posts/:id', (req, res) => {
const postId = parseInt(req.params.id, 10);
const postIndex = posts.findIndex(p => p.id === postId);
if (postIndex !== -1) {
posts.splice(postIndex, 1);
res.status(204).send();
} else {
res.status(404).send('Post not found');
}
});
app.delete()
to handle DELETE requests to /posts/:id
.posts
array.204 No Content
status code is sent; otherwise, a 404 Not Found
status code is sent.To handle errors in a consistent way, we can add an error-handling middleware:
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).send('Something broke!');
});
Here’s the complete code for our simple blog API:
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
const port = 3000;
app.use(bodyParser.json());
let posts = [];
app.get('/', (req, res) => {
res.send('Welcome to the Blog API');
});
app.post('/posts', (req, res) => {
const { title, content } = req.body;
const newPost = { id: posts.length + 1, title, content };
posts.push(newPost);
res.status(201).json(newPost);
});
app.get('/posts', (req, res) => {
res.json(posts);
});
app.get('/posts/:id', (req, res) => {
const postId = parseInt(req.params.id, 10);
const post = posts.find(p => p.id === postId);
if (post) {
res.json(post);
} else {
res.status(404).send('Post not found');
}
});
app.put('/posts/:id', (req, res) => {
const postId = parseInt(req.params.id, 10);
const { title, content } = req.body;
const postIndex = posts.findIndex(p => p.id === postId);
if (postIndex !== -1) {
posts[postIndex] = { id: postId, title, content };
res.json(posts[postIndex]);
} else {
res.status(404).send('Post not found');
}
});
app.delete('/posts/:id', (req, res) => {
const postId = parseInt(req.params.id, 10);
const postIndex = posts.findIndex(p => p.id === postId);
if (postIndex !== -1) {
posts.splice(postIndex, 1);
res.status(204).send();
} else {
res.status(404).send('Post not found');
}
});
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).send('Something broke!');
});
app.listen(port, () => {
console.log(`Server is running on http://localhost:${port}`);
});
Use Postman or a similar tool to test the API. Here are the endpoints you can test:
POST http://localhost:3000/posts
{"title": "First Post", "content": "This is the content of the first post"}
GET http://localhost:3000/posts
GET http://localhost:3000/posts/1
PUT http://localhost:3000/posts/1
{"title": "Updated Post", "content": "This is the updated content"}
DELETE http://localhost:3000/posts/1
Handling requests and responses is a core aspect of web development, and Express.js simplifies this process significantly. From handling different HTTP methods, working with parameters and body data, setting headers and status codes, to using middleware and managing errors, Express.js provides a comprehensive toolkit for developing robust web applications. By mastering these concepts, you can create efficient and scalable web applications using Express.js.Happy coding !❤️