Express Routing
Workplace Context
Your team is building a new API for an e-commerce platform. To make the API useful, it needs to handle various types of requests. For example, it must be able to fetch a specific product by its ID, search for products based on user criteria, and allow users to submit new product reviews. This requires a robust routing system that can handle dynamic data passed in the URL or in the request itself.
Learning Objectives
By the end of this lesson, you will be able to:
- Differentiate between
GET
andPOST
requests and their use cases. - Create dynamic routes using route parameters (
req.params
) to handle required data. - Handle optional data using query strings (
req.query
). - Access data from the request body (
req.body
) using the appropriate middleware. - Choose the correct method (
params
,query
, orbody
) to get data from a request.
What is Routing?
Routing refers to how an application’s endpoints (URIs) respond to client requests. In Express, we define routes that listen for a specific HTTP request method (GET
, POST
, etc.) and a specific URL path. When a match is found, a designated function is called to handle the request.
So far, we’ve only seen app.get('/', ...)
, which handles GET
requests for the root URL. Now let’s explore more powerful routing capabilities.
GET
vs. POST
: When to Use Which?
GET
and POST
are the two most common HTTP methods you will encounter.
-
GET
: Used to request or retrieve data from a server.- Analogy: Asking a librarian for a specific book. You are not changing the library’s collection; you are just retrieving information.
- Use Case: Loading a user’s profile page, fetching a list of products, or getting a single blog post.
- Key Trait:
GET
requests should be “safe” and “idempotent,” meaning they don’t change anything on the server, and making the same request multiple times has the same effect as making it once. Data is sent in the URL (via params or query strings).
-
POST
: Used to send data to a server to create a new resource.- Analogy: Submitting an application form to a university. You are adding new data to their system.
- Use Case: Creating a new user account, submitting a new blog post, or adding a product to a shopping cart.
- Key Trait:
POST
requests change the state of the server. The data for the new resource is sent in the request body, not the URL.
In Express, you handle these with app.get()
and app.post()
.
Three Ways to Get Data from a Request
A client can send data to your server in three primary ways. Understanding the difference is critical for building a good API.
1. Route Parameters (req.params
)
Use Case: For required, essential pieces of data that are part of the URL path itself. This is most common for unique identifiers.
Think of the URL as a house address. The path /users/123
is like saying, “I need the user at house number 123.” The ID 123
is a required part of the address. Without it, you can’t find the house.
You define a route parameter in your Express route path by prefixing it with a colon (:
). Express then captures the value from the URL and makes it available in the req.params
object.
const express = require('express');
const app = express();
const port = 3000;
// The ':userId' is a route parameter.
// This route will match /users/1, /users/abc, etc.
app.get('/users/:userId', (req, res) => {
// Express captures the value and puts it in req.params
const id = req.params.userId;
res.send(`You requested user with the required ID: ${id}`);
});
// You can have multiple parameters
app.get('/books/:bookId/chapter/:chapterNum', (req, res) => {
const book = req.params.bookId;
const chapter = req.params.chapterNum;
res.send(`You are viewing Chapter ${chapter} of Book ${book}.`);
});
app.listen(port, () => {
console.log(`Server is running at http://localhost:${port}`);
});
2. Query Strings (req.query
)
Use Case: For optional filtering, sorting, or searching criteria.
Think of a query string as adding special instructions to your request. If you go to a pizza place, the base request is “I want a pizza” (/pizzas
). The query string is how you add optional details: ?size=large&topping=pepperoni
. The pizza still exists without these options, but they help refine the result.
A query string starts with a ?
and is made of key=value
pairs, separated by &
. Express automatically parses this string into the req.query
object for you.
const express = require('express');
const app = express();
const port = 3000;
// Example URL: /search?q=javascript&sort=popular
app.get('/search', (req, res) => {
const searchTerm = req.query.q || 'nothing';
const sortBy = req.query.sort || 'relevance';
res.send(`You optionally searched for '${searchTerm}' and sorted by '${sortBy}'.`);
});
app.listen(port, () => {
console.log(`Server is running at http://localhost:${port}`);
});
3. Request Body (req.body
)
Use Case: For sending complex or large amounts of data, almost always with POST
(or other data-mutating) requests.
Think of the request body as a package you are mailing. The URL is the address on the outside of the box, but the actual contents (the data) are inside the box. This is perfect for sending structured data, like a JSON object with a new user’s information, which would be too long and clunky to put in a URL.
By default, Express does not know how to read the “contents of the box.” We need to use middleware to act as a translator. The express.json()
middleware tells our server how to parse incoming data that is in JSON format.
const express = require('express');
const app = express();
const port = 3000;
// This middleware 'translator' is essential for req.body to work
app.use(express.json());
app.post('/api/users', (req, res) => {
// req.body contains the JSON data sent by the client
const newUser = req.body;
console.log('Received new user from request body:', newUser);
// A real app would save this to a database
res.status(201).send(`User ${newUser.name} created successfully.`);
});
app.listen(port, () => {
console.log(`Server is running at http://localhost:${port}`);
});
How do you test this? You can’t just type a
POST
request into a browser’s address bar. You need a special tool called an API client. Postman is a very popular and powerful tool for this purpose that you will use throughout your career. While it is outside the scope of this course, you can learn more about it here .
Summary of Data Sources
Method | Express Object | Use Case | Example URL |
---|---|---|---|
Route Params | req.params | Required identifiers | /users/123 |
Query String | req.query | Optional sorting/filtering | /products?category=laptops |
Request Body | req.body | Complex data for creation | POST /users |
Activities
Activity 1: Dynamic Product Route
- Create an Express server.
- Implement a route
GET /products/:productId
that captures the product ID from the URL usingreq.params
. - The route should respond with a message like
"Fetching data for product with the required ID: <productId>"
. - Test your route with different product IDs in the browser.
Activity 2: API Search Route
- Create another route
GET /api/products
. - This route should check for optional query parameters from
req.query
, such ascategory
andminPrice
. - If the query parameters exist, it should respond with a descriptive message, e.g.,
"Searching for products in category <category> with a minimum price of <minPrice>"
. - If they don’t exist, it should respond with
"Showing all products"
. - Test this with different query strings in your browser (e.g.,
/api/products?category=electronics&minPrice=500
).
Knowledge Check
In the URL /books/978-0321765723
, how would you access the book's ID in an Express route?
- Select an answer to view feedback.
A client sends a GET
request to /api/v1/items?sort=desc&limit=10
. How would you access the limit
value?
- Select an answer to view feedback.
Which middleware is required for your server to be able to read JSON data sent in a POST
request?
- Select an answer to view feedback.
Summary
In this lesson, you explored the core of how Express handles web traffic: routing. You learned how to create routes for different HTTP methods and, most importantly, the three key ways to get data from a client: required route parameters (req.params
), optional query strings (req.query
), and complex request bodies (req.body
). Understanding when and how to use each of these is essential for building any RESTful API or dynamic web application.