Fetching a Single User

Introduction: Why Fetch a Single Item?

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.


Quick Recap: App Structure and Mock Data

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:

// src/lib/data.ts
export const users = [
  { id: 1, name: 'Alice', email: 'alice@example.com' },
  { id: 2, name: 'Bob', email: 'bob@example.com' },
  // ...more users
];

// src/app/api/users/route.ts (for POST requests)
import { users } from '@/lib/data';
// ...POST handler code

You do not need to set this up again, but keep in mind that the users array is our mock database for this lesson.


Dynamic Routes In Next.js API

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:

src/app/api/users/[id]/route.ts

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.


Building The GET Handler For A Single User

Let’s look at the code for handling a GET request to fetch a single user by ID. Here is the complete handler:

import { NextResponse, type NextRequest } from 'next/server';
import { users } from '@/lib/data';

type RouteParams = {
  params: {
    id: string;
  };
};

/**
 * Handles GET requests to /api/users/[id].
 * Retrieves a single user by their ID.
 */
export async function GET(request: NextRequest, { params }: RouteParams) {
  // The 'id' from the URL is available in the 'params' object
  const userId = parseInt(params.id, 10);

  // Find the user in our mock database
  const user = users.find((u) => u.id === userId);

  // If the user is not found, return a 404 response
  if (!user) {
    return NextResponse.json(
      { error: 'User not found' },
      { status: 404 }
    );
  }

  // If the user is found, return it with a 200 OK status
  return NextResponse.json(user);
}

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 called id 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 using params.id and convert it to a number with parseInt.
  • We search the users array for a user with a matching id.
  • If the user is found, we return their data as JSON.
  • If the user is not found, we return a JSON error message with a 404 status.
Sign up

Join the 1M+ learners on CodeSignal

Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal