Skip to main content

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:

javascript
app.method(path, handler);

Where:

  • app is your Express application instance
  • method is the HTTP method in lowercase
  • path is the URL path on your server
  • handler 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.

javascript
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.

javascript
// 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.

javascript
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.

javascript
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.

javascript
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:

javascript
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:

javascript
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:

bash
curl http://localhost:3000/api/books

Get a specific book:

bash
curl http://localhost:3000/api/books/1

Create a new book:

bash
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:

bash
curl -X PUT -H "Content-Type: application/json" -d '{"title": "Updated Title", "author": "Updated Author"}' http://localhost:3000/api/books/2

Delete a book:

bash
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:

javascript
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

  1. Create a simple Express API for a "todo" app with endpoints to list, create, update, and delete todo items.
  2. Modify the books API example to include searching by title or author using query parameters.
  3. Implement proper error handling for all endpoints in the books API.
  4. Add validation to ensure that POST and PUT requests include all required fields.
  5. 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! :)