Express Route Methods
When building web applications with Express.js, handling different types of HTTP requests is a fundamental concept. Express provides a clean and intuitive way to define routes for various HTTP methods, allowing you to create powerful and RESTful APIs.
Introduction to HTTP Methods
HTTP methods (also called verbs) define the type of action that a client wants to perform on a server resource. In Express routing, these methods correspond to different functions you can use to handle requests:
- GET: Retrieve data from the server
- POST: Submit data to be processed
- PUT: Update existing resources
- DELETE: Remove resources
- PATCH: Partially update resources
- OPTIONS: Get information about the communication options
- HEAD: Similar to GET but only returns headers, no body
Basic Route Method Syntax
In Express, route methods follow this basic pattern:
app.method(path, handler);
Where:
app
is your Express application instancemethod
is the HTTP method in lowercasepath
is the URL path on your serverhandler
is the callback function executed when the route is matched
Common HTTP Methods in Express
GET Requests
GET requests are used to retrieve data. They should not modify any data on the server.
const express = require('express');
const app = express();
// Define a basic GET route
app.get('/users', (req, res) => {
// This handler runs when a client makes a GET request to /users
res.send('List of all users');
});
// GET route with URL parameters
app.get('/users/:id', (req, res) => {
const userId = req.params.id;
res.send(`Details for user ${userId}`);
});
POST Requests
POST requests are typically used to create new resources or submit data.
// Middleware to parse JSON bodies
app.use(express.json());
app.post('/users', (req, res) => {
// Access the data sent in the request body
const newUser = req.body;
// In a real app, you would save this to a database
console.log('Creating new user:', newUser);
// Send back a response
res.status(201).send({
message: 'User created successfully',
user: newUser
});
});
PUT Requests
PUT requests are used to update existing resources by replacing them entirely.
app.put('/users/:id', (req, res) => {
const userId = req.params.id;
const updatedUserData = req.body;
console.log(`Updating user ${userId} with data:`, updatedUserData);
// In a real app, you would update this in your database
res.send({
message: `User ${userId} updated successfully`,
user: updatedUserData
});
});
DELETE Requests
DELETE requests are used to remove resources.
app.delete('/users/:id', (req, res) => {
const userId = req.params.id;
// In a real app, you would delete from your database
console.log(`Deleting user ${userId}`);
res.send({
message: `User ${userId} deleted successfully`
});
});
PATCH Requests
PATCH requests are used for partial updates to resources.
app.patch('/users/:id', (req, res) => {
const userId = req.params.id;
const updates = req.body;
// In a real app, you would update specific fields in your database
console.log(`Partially updating user ${userId} with:`, updates);
res.send({
message: `User ${userId} partially updated`,
updates: updates
});
});
Chaining Route Methods
Express allows you to chain methods for the same route path, making your code more concise:
app.route('/books')
.get((req, res) => {
res.send('Get all books');
})
.post((req, res) => {
res.send('Add a new book');
})
.put((req, res) => {
res.send('Update all books');
});
// Chain routes for a specific book
app.route('/books/:id')
.get((req, res) => {
res.send(`Get book ${req.params.id}`);
})
.put((req, res) => {
res.send(`Update book ${req.params.id}`);
})
.delete((req, res) => {
res.send(`Delete book ${req.params.id}`);
});
Real-World Example: Building a Simple API
Let's create a simple in-memory "books" API to demonstrate the different route methods:
const express = require('express');
const app = express();
const port = 3000;
// Middleware for parsing JSON
app.use(express.json());
// In-memory "database" of books
let books = [
{ id: 1, title: 'The Great Gatsby', author: 'F. Scott Fitzgerald' },
{ id: 2, title: 'To Kill a Mockingbird', author: 'Harper Lee' },
{ id: 3, title: '1984', author: 'George Orwell' }
];
// GET all books
app.get('/api/books', (req, res) => {
res.json(books);
});
// GET a single book
app.get('/api/books/:id', (req, res) => {
const book = books.find(b => b.id === parseInt(req.params.id));
if (!book) {
return res.status(404).json({ message: 'Book not found' });
}
res.json(book);
});
// POST a new book
app.post('/api/books', (req, res) => {
const newBook = {
id: books.length + 1,
title: req.body.title,
author: req.body.author
};
books.push(newBook);
res.status(201).json(newBook);
});
// PUT to update a book
app.put('/api/books/:id', (req, res) => {
const bookId = parseInt(req.params.id);
const bookIndex = books.findIndex(b => b.id === bookId);
if (bookIndex === -1) {
return res.status(404).json({ message: 'Book not found' });
}
const updatedBook = {
id: bookId,
title: req.body.title,
author: req.body.author
};
books[bookIndex] = updatedBook;
res.json(updatedBook);
});
// DELETE a book
app.delete('/api/books/:id', (req, res) => {
const bookId = parseInt(req.params.id);
const bookIndex = books.findIndex(b => b.id === bookId);
if (bookIndex === -1) {
return res.status(404).json({ message: 'Book not found' });
}
const deletedBook = books[bookIndex];
books = books.filter(b => b.id !== bookId);
res.json({
message: 'Book deleted successfully',
deletedBook: deletedBook
});
});
// Start the server
app.listen(port, () => {
console.log(`API running on http://localhost:${port}`);
});
Example API Interactions
Here's how you would interact with this API using curl
or a similar HTTP client:
Get all books:
curl http://localhost:3000/api/books
Get a specific book:
curl http://localhost:3000/api/books/1
Create a new book:
curl -X POST -H "Content-Type: application/json" -d '{"title": "The Hobbit", "author": "J.R.R. Tolkien"}' http://localhost:3000/api/books
Update a book:
curl -X PUT -H "Content-Type: application/json" -d '{"title": "Updated Title", "author": "Updated Author"}' http://localhost:3000/api/books/2
Delete a book:
curl -X DELETE http://localhost:3000/api/books/3
Method Not Allowed Response
When a client uses an HTTP method that is not supported for a particular route, it's good practice to return a "405 Method Not Allowed" status:
app.all('/api/books/:id', (req, res, next) => {
if (['GET', 'PUT', 'DELETE'].includes(req.method)) {
next();
} else {
res.status(405).send('Method Not Allowed');
}
});
Summary
Express route methods provide an elegant way to handle different types of HTTP requests, making it easy to build RESTful APIs:
- GET: Retrieve data
- POST: Create new resources
- PUT: Update resources by replacement
- DELETE: Remove resources
- PATCH: Partially update resources
- OPTIONS/HEAD: Get metadata about resources
When designing your API, follow REST principles:
- Use appropriate HTTP methods for each action
- Return appropriate status codes
- Structure your endpoints around resources
By mastering Express route methods, you can create clean, intuitive, and powerful APIs for your web applications.
Additional Resources
Exercises
- Create a simple Express API for a "todo" app with endpoints to list, create, update, and delete todo items.
- Modify the books API example to include searching by title or author using query parameters.
- Implement proper error handling for all endpoints in the books API.
- Add validation to ensure that POST and PUT requests include all required fields.
- Extend the books API to include a PATCH endpoint that allows updating only specific fields of a book.
If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)