Introduction: Why Update and Delete?

Welcome back! So far, you have learned how to create new users with POST and fetch a single user with a GET request. In real-world applications, it is just as important to be able to update and delete data. For example, users might want to edit their profile information or remove their account entirely. In this lesson, you will learn how to handle these actions using the PUT and DELETE methods in a Next.js API route.

By the end of this lesson, you will know how to update a user’s information and remove a user from your data store. These are essential skills for building any full-featured backend.


Recap: Our API Route and Data Setup

Before we dive into updating and deleting, let’s quickly remind ourselves of the setup we have been using. We have a simple array of users and a dynamic API route that handles requests for a specific user by their ID.

Here is a quick look at the setup:

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

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

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);
}
  • users is our in-memory array that stores user objects.
  • The route uses a dynamic segment [id] to handle requests for a specific user.

This setup allows us to easily find a user by their ID.


PUT Method: Updating a User

The PUT method is used to update an existing resource. In our case, it lets us update a user’s details. Let’s look at the code for handling a PUT request:

export async function PUT(request: NextRequest, { params }: RouteParams) {
  const userId = parseInt(params.id, 10);
  const idx = users.findIndex(u => u.id === userId);
  if (idx === -1) {
    return NextResponse.json({ error: 'User not found' }, { status: 404 });
  }

  const updatedData = await request.json();
  users[idx] = { id: userId, ...updatedData }; 
  return NextResponse.json(users[idx]);
}

Let’s break this down:

  • We get the user ID from the URL and look for the user in our array.
  • If the user is not found, we return a 404 error with a message.
  • If the user exists, we read the new data from the request body.
  • We update the user’s information in the array, keeping the same ID.
  • Finally, we return the updated user as a JSON response.

Example:
Suppose you send a PUT request to /api/users/2 with this JSON body:

{
  "name": "Alex Smith",
  "email": "alex.smith@example.com"
}

If user 2 exists, the response will be:

{
  "id": 2,
  "name": "Alex Smith",
  "email": "alex.smith@example.com"
}

If user 2 does not exist, you will get:

{
  "error": "User not found"
}

with a status code of 404.

⚠️ Important: This implementation assumes you're replacing the entire user object (except for the id). If the client sends only a partial object (e.g., just a "name" field), the email will be lost. This is how the PUT method works: it's designed to fully replace the resource, not partially update it.

For example, sending:

{
  "name": "Alex Smith"
}

would result in this:

{
  "id": 2,
  "name": "Alex Smith"
  // No email field anymore
}

In a real application, you'd either:

  • Require all fields on every PUT, or
  • Use PATCH if you want to allow partial updates (we’ll explore this in later units).

For now, just remember: if you're using PUT, send all fields the user should have.


DELETE Method: Removing a User

The DELETE method is used to remove a resource. Here is how we handle deleting a user:

export async function DELETE(request: NextRequest, { params }: RouteParams) {
  const userId = parseInt(params.id, 10);
  const userIndex = users.findIndex((u) => u.id === userId);

  if (userIndex === -1) {
    return NextResponse.json({ error: 'User not found' }, { status: 404 });
  }

  // Remove the user from the array
  users.splice(userIndex, 1);

  // Return a success response with no content
  return new NextResponse(null, { status: 204 });
}

Here is what is happening:

  • We get the user ID from the URL and look for the user in the array.
  • If the user is not found, we return a 404 error.
  • If the user exists, we remove them from the array using splice.
  • We return a response with status 204, which means the request was successful but there is no content to return. The 204 status code tells the client: “The resource was deleted successfully, and there's nothing else to show.” This avoids sending unnecessary data back and is more semantically accurate than 200 OK.

Example:
If you send a DELETE request to /api/users/3 and user 3 exists, the response will have status 204 and no content:

Status: 204 No Content

If user 3 does not exist, you will get:

{
  "error": "User not found"
}

with a status code of 404.


How the Frontend Triggers PUT and DELETE
Summary And Practice Preview

In this lesson, you learned how to update user data with the PUT method and remove users with the DELETE method in a Next.js API route. You saw how to find users by their ID, handle cases where the user does not exist, and return the right responses for each situation.

These skills are essential for building real-world APIs that let users manage their own data. Up next, you will get to practice updating and deleting users yourself. Congratulations on mastering the basics of handling data in a Next.js API!

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