- Express.js Basics
- Express.js HOME
- Express.js Introduction
- Express.js Installation
- Express.js Basic App
- Express.js Routing
- Basics Routing
- Route Parameters
- Handling Query Strings
- Router Middleware
- Middleware
- What is Middleware?
- Application-Level Middleware
- Router-Level Middleware
- Built-In Middleware
- Error-Handling Middleware
- Third-Party Middleware
- Express.js HTTP
- Handling GET Requests
- Handling POST Requests
- Handling PUT Requests
- Handling DELETE Requests
- Templating Engines
- Using Templating Engines
- Setting Up EJS
- Setting Up Handlebars
- Setting Up Pug
- Request/Response
- Request Object
- Response Object
- Handling JSON Data
- Handling Form Data
- Static Files
- Serving Static Files
- Setting Up Static Folders
- Managing Assets
- Express.js Advanced
- Middleware Stack
- CORS in Express.js
- JWT Authentication
- Session Handling
- File Uploads
- Error Handling
- Databases
- Express.js with MongoDB
- MongoDB CRUD Operations
- Express.js with MySQL
- MySQL CRUD Operations
- Deployment
- Deploying Express.js Apps to Heroku
- Deploying Express.js Apps to AWS
- Deploying Express.js Apps to Vercel
Express.js Handling PUT Requests
In the world of RESTful APIs, PUT requests are the standard way to update existing data on a server. While a POST request is typically used to create a brand-new resource, a PUT request is designed to replace a specific resource or create it if it doesn't exist at a specific URL. In Express.js, we handle these using the app.put() method.
Key Features of Handling PUT Requests
- Resource Updating: PUT is primary used when you know the exact URI of the resource you want to modify (e.g.,
/api/users/42). - Request Body: Unlike GET requests, PUT requests carry a payload (usually JSON) containing the new state of the resource.
- Idempotent Operation: This is a fancy way of saying that making the same PUT request multiple times will have the same result as making it once. The resource state won't change after the first successful update.
- Data Validation: Since you are modifying your database, you must ensure the incoming data is safe, complete, and formatted correctly.
Handling Basic PUT Requests
To handle a PUT request, you define a route that includes a unique identifier (like an ID) in the URL. This allows Express to know exactly which record you intend to change.
express.json() middleware, or req.body will be undefined.
Example:
const express = require('express');
const app = express();
// Essential middleware to read JSON bodies
app.use(express.json());
let users = [
{ id: 1, name: 'John Doe' },
{ id: 2, name: 'Jane Smith' }
];
// Handle PUT request to update user data
app.put('/user/:id', (req, res) => {
const userId = parseInt(req.params.id);
const updatedData = req.body;
const userIndex = users.findIndex(u => u.id === userId);
if (userIndex === -1) {
return res.status(404).json({ message: 'User not found' });
}
// Overwrite the existing user data
users[userIndex] = { id: userId, ...updatedData };
res.send(`User updated successfully: ${JSON.stringify(users[userIndex])}`);
});
app.listen(3000, () => {
console.log('Server running on http://localhost:3000');
});
req.params.id is always a string. Always use parseInt() or Number() if your data IDs are integers, otherwise, comparisons like u.id === req.params.id will fail.
Handling PUT Requests with Validation
Never trust data sent by a client. Before updating your records, check that the required fields exist and meet your application's rules. If the data is invalid, return a 400 Bad Request status code.
Example:
app.put('/user/:id', (req, res) => {
const { name, email } = req.body;
// Simple validation logic
if (!name || !email) {
return res.status(400).send('Missing required fields: name and email are mandatory.');
}
const userId = parseInt(req.params.id);
const user = users.find(u => u.id === userId);
if (!user) {
return res.status(404).send('User not found');
}
user.name = name;
user.email = email;
res.json({ message: 'User updated', data: user });
});
Handling PUT Requests with Asynchronous Operations
In real-world applications, you'll likely be updating data in a database like MongoDB or PostgreSQL. These operations take time, so you should use async/await and include error handling to catch database connection issues.
Example:
app.put('/user/:id', async (req, res) => {
try {
const { name } = req.body;
const userId = req.params.id;
// Simulating a database update (e.g., Mongoose or Sequelize)
const updatedUser = await User.findByIdAndUpdate(userId, { name }, { new: true });
if (!updatedUser) {
return res.status(404).send('User not found in database');
}
res.json(updatedUser);
} catch (error) {
console.error(error);
res.status(500).send('Internal Server Error');
}
});
Handling PUT Requests with Middleware
Middleware is perfect for tasks that need to happen before the update logic runs, such as checking if a user is authorized or logging the request details.
Example:
// Middleware to log update attempts
const logUpdate = (req, res, next) => {
console.log(`Update attempt for ID: ${req.params.id} at ${new Date().toISOString()}`);
next();
};
app.put('/user/:id', logUpdate, (req, res) => {
// Process the update after the middleware runs
res.send('Update logic processed');
});
Handling PUT Requests with Multiple Parameters
Sometimes an update depends on multiple factors in the URL. For example, you might want to update a specific post belonging to a specific user. Express handles this easily by defining multiple named parameters.
Example:
// URL: /user/10/post/5
app.put('/user/:userId/post/:postId', (req, res) => {
const { userId, postId } = req.params;
const { content } = req.body;
// Logic to find post #5 belonging to user #10 and update content
res.send(`Updated post ${postId} for user ${userId} with new content: ${content}`);
});
Summary
Mastering PUT requests is a cornerstone of building functional APIs in Express.js. By using app.put(), you provide a clear, idempotent way for clients to modify resources. Remember to always use middleware to parse your JSON bodies, validate incoming data to protect your database, and use async/await for non-blocking database operations. When implemented correctly, PUT requests ensure your API follows standard REST principles, making it predictable and easy for other developers to use.