Welcome back! In the previous lesson, you learned how to create new users using the POST method in a Next.js API route. Now, let’s look at another common task: fetching a single item, such as a user, by its unique identifier.
In real-world applications, you often need to display details for a specific item. For example, when you click on a user’s name in a list, you expect to see their profile page. To make this work, your backend needs to handle requests for a specific user and return only that user’s data.
In this lesson, you will learn how to set up a dynamic route in Next.js to fetch a single user by their ID. This is a key skill for building APIs that support user profiles, product pages, and more.
Before we dive in, let’s quickly remind ourselves of the setup you already have. You have a Next.js project with an API route for users and a mock array of user data. Here’s a summary of the relevant parts:
You do not need to set this up again, but keep in mind that the users
array is our mock database for this lesson.
To fetch a single user, we need a way to handle requests like /api/users/2
, where 2
is the user’s ID. Next.js makes this easy with dynamic routes.
A dynamic route uses square brackets in the file name to capture part of the URL as a parameter. For example:
In this case, [id]
means any request to /api/users/<some-id>
will be handled by this file, and the <some-id>
part (like 2
, 17
, or 99
) will be passed as a string parameter named id
.
This allows us to write code that responds to requests for any user, not just a specific one.
Let’s look at the code for handling a GET request to fetch a single user by ID. Here is the complete handler:
Let’s break down what’s happening here:
- We import the
users
array and the necessary Next.js types. - The
RouteParams
type tells us that we expect a parameter calledid
from the URL. - The
GET
function is called when a GET request is made to/api/users/[id]
. - We extract the
id
from the URL usingparams.id
and convert it to a number withparseInt
. - We search the
users
array for a user with a matchingid
. - If the user is found, we return their data as JSON.
Even though this GET
handler is short, it’s doing a few important things behind the scenes. Let’s walk through what happens when someone visits /api/users/2
.
- Dynamic route: The file name [id].ts tells Next.js to treat anything after /api/users/ as a dynamic segment and pass it into the handler as params.id.
- Parsing the ID: The value of params.id is a string (e.g., "2"), so we convert it into a number using parseInt. This is important because the id field in our users array is a number.
- Finding the user: We use .find() to search the array. If the ID matches, we return that user; otherwise, we send a 404.
- Why do we use
parseInt(..., 10)
?- The second argument (
10
) ensures the string is parsed in base-10. This is a best practice to avoid unexpected behavior when working with numeric strings (especially ones that might start with0
, like"08"
).
- The second argument (
Example Request and Output
Suppose you make a GET request to /api/users/2
. If user 2 exists, the response will look like:
If you request a user who does not exist, like /api/users/99
, the response will be:
With a status code of 404.
It’s important to handle cases where the requested user does not exist. In the code above, we check if user
is undefined
(not found) and return a 404 error with a clear message.
This helps clients of your API (like frontend apps) know when they’ve requested something that isn’t there, so they can show a helpful message to the user.
Why is this important?
- It prevents confusion for users and developers.
- It follows best practices for REST APIs.
- It makes your API more reliable and predictable.
💡 Pro Tip: Returning 404 for “not found” and 400 for “bad input” helps frontend developers (and API testers) understand whether the issue was with what they asked for (missing user) or how they asked for it (invalid ID). You’ll see this practice often in robust APIs.
Just like in the previous lesson where the frontend triggered a POST
request, there's also a small function in src/app/page.tsx
that fetches a single user by their ID.
Here’s how it looks:
What's happening here:
- This function runs when the "Get User by ID" button is clicked.
- It first checks if an ID is provided (e.g.
2
). - Then it sends a
GET
request to/api/users/2
(or whatever ID was entered). - The response is logged so you can see what the server returned — whether it's the user data or an error like
"User not found"
.
You don’t need to focus on the React logic here, but it’s helpful to understand how your backend API is being used in a real interface.
In this lesson, you learned how to fetch a single user by their ID using a dynamic route in Next.js. You saw how to:
- Set up a dynamic route with
[id]
in the file name. - Extract the ID from the URL.
- Find the user in your data.
- Return the user’s data or a 404 error if not found.
Next, you’ll get a chance to practice these skills with hands-on exercises. This will help you get comfortable with dynamic routes and handling single-item requests in your own projects. Good luck!
