Welcome! In this lesson, we will focus on the POST method, which is a key part of working with data in web applications. The POST method is used when you want to create new data on the server, such as adding a new user to a database.
When you fill out a form on a website and click "submit," your browser often sends a POST request to the server. The server then processes the data and stores it. Learning how to handle POST requests is an important first step in building your own backend APIs.
By the end of this lesson, you will know how to accept data from a client, validate it, and add it to your data store using Next.js API routes.
Before we dive into handling POST requests, let’s quickly review the basic setup you’ll be working with. In this course, we use a Next.js API route to handle requests, and we store our user data in a simple in-memory array.
Here’s a summary of the setup:
- We import
NextResponseandNextRequestfrom Next.js to handle API requests and responses. - The
usersarray holds our user data in memory (not in a real database). - The
GETfunction returns all users as a JSON response.
Note: Keep in mind that in-memory storage is temporary—if the server restarts, the data will be lost. In a production application, this logic would typically interact with a persistent database like PostgreSQL, MongoDB, or SQLite. We're using an array here to simplify the focus on API logic rather than database setup.
This setup allows us to focus on how to handle POST requests without worrying about database setup for now.
To create new data, we need to handle POST requests in our API route. In Next.js App Router, each HTTP method corresponds to a separate function (GET, POST, PUT, etc.) that you export from the same file.
In real-world applications, you might also need to configure CORS (Cross-Origin Resource Sharing) or set headers such as
Content-Type: application/jsonon the client request. While this is handled automatically in many setups, it's worth being aware of when integrating with other frontends or third-party tools.
Here’s how you can define a POST handler:
Let’s break down what’s happening here:
- The function receives a
requestobject. - It reads the JSON body from the request using
await request.json().
Let’s walk through the process step by step using the code above.
- Receive User Data
The lineconst newUser: Omit<User, 'id'> = await request.json();reads the data sent by the client. Theawait request.json()method reads the body of the incoming request and parses it as JSON. If the request body is not valid JSON, this line will throw an error, which is why we have atry-catchblock to handle such cases. For example, the client might send:
We use Omit<User, 'id'> to indicate that the client is not expected to send an id value, since it's the server's responsibility to generate it. This helps ensure type safety and makes it explicit that the server handles the assignment of IDs, not the client.
-
Validate Required Fields
The code checks if bothnameandemailare present. If either is missing, it returns:with a status code of
400. -
Generate a New User ID
The code finds the highest existing user ID and adds 1 to it. This ensures that each user has a unique ID. -
Add the User to the Array
The new user object is created and pushed into theusersarray. -
Return the New User
If everything is valid, the server responds with the new user and a status code of , indicating that the server successfully created a resource:
It’s important to handle errors gracefully. In the example above, there are two main places where errors can happen:
-
Missing or Invalid Data:
If the client does not provide both anameand anemail, the server responds with a clear error message and a400status code. -
Invalid JSON:
If the request body is not valid JSON, thecatchblock will handle it and return:with a
400status code.
This helps clients understand what went wrong and how to fix their request.
While this course focuses on backend logic, it's helpful to understand how the frontend actually sends a POST request to your API route. In the provided src/app/page.tsx file, there's a handleCreate function that calls your /api/users route when a user submits a name and email.
Here’s the simplified version of that logic:
What's happening here:
- It sends a
POSTrequest to/api/usersusing the built-infetchfunction. - The request body is a JSON string containing the
nameandemailvalues from user input. - It also includes the
Content-Type: application/jsonheader so the backend knows how to parse the data. - The server receives the request and processes it using the
POSThandler you wrote earlier.
You don't need to master the frontend here—but knowing how the backend is triggered from the client will help you test, debug, and build complete features confidently.
In this lesson, you learned how to handle POST requests in a Next.js API route to create new data. You saw how to:
- Read and validate data from the request body
- Generate a unique ID for new users
- Add new users to an in-memory data store
- Return the correct status codes and error messages
Next, you’ll get a chance to practice these steps yourself. You’ll write your own POST handlers, test them, and see how data is created and returned. This hands-on practice will help you become comfortable with creating new data in your own backend APIs.
