Building API Using Next.js
July 30th, 2024 | By Jay Raj | 10 min read
In this tutorial, you'll learn how to build APIs using Next.js 14. The newer version of Next.js provides the platform to create APIs using the App router.
Let's start by creating our Next.js 14 project. As a prerequisite, you'll be required to have Node.js 18.17 or later to work with Next.js 14. You can check the Node.js version currently installed in your system. For that open your command prompt and type in the following command,
node --version
which will output something like,
v20.10.0
If you already have the required version installed you are good to go. Otherwise, you can install the latest Node.js version.
Once you have the required Node.js installed, you can start by creating a new Next.js project using `create-next-app`.
npx create-next-app@latest
The above command will prompt for a couple of questions related to the project creation,
√ What is your project named? ... next-14-api
√ Would you like to use TypeScript? ...Yes
√ Would you like to use ESLint? ... No
√ Would you like to use Tailwind CSS? ... No
√ Would you like to use `src/` directory? ...Yes
√ Would you like to use App Router? (recommended) ... Yes
√ Would you like to customize the default import alias (@/*)? ... No
Fill in the response as shown above and once done you will have the boilerplate Next.js project ready to run.
Navigate to the project directory and run the project.
cd next-14-api
npm run dev
Point your browser to http://localhost:3000 and you will have the default project running.
Building API Using Next.js: Project Structure
You have the ' src ' folder inside the project folder, `next-14-api`. All the project source code resides inside the `src` folder. Inside the `src` folder create a folder called `api` which will serve as the main folder for our Next.js APIs.
Once you have the `api` folder, create a folder called `users`, and inside `users` create a file called `route.ts`. Every API endpoint will have a file called `route.ts`.
Here in our case, since there is `route.ts` inside the `api/users/` folder, the API endpoint will be `/api/users`.
GET API Endpoint
To begin with, let's create an API endpoint inside the `route.ts` file. Start by defining a function for a GET request as shown.
typescript
const GET = () => {
return Response.json({"status":200, "message":"SUCCESS"})
}
export {GET}
As seen in the above method, we are returning a JSON response for the API endpoint's GET request. To test the GET request API endpoint, you can restart the application. Once the application is up and running try accessing the endpoint using http://localhost:3000/api/users and you will be able to see the response.
{"status":200,"message":"SUCCESS"}
In addition to what we defined in the above GET method, let's make it a bit more realistic by adding an API call inside the GET method. For that, you need to mark the method as `async` since we'll be using `await` to fetch the data from API.
typescript
const GET = async () => {
const response = await fetch('https://jsonplaceholder.typicode.com/users');
const responseData = await response.json();
return Response.json({"status":200, "data": responseData})
}
export {GET}
In the above code, we are making an API request to an external API endpoint and then returning the received data as the response from our `/api/users` endpoint.
Save the above changes and try making a GET request to http://localhost:3000/api/users and you'll be able to see a JSON response with data from the external API endpoint.
Now, let's have a look at how you can read the query parameters from the API endpoint. Here is how you can pass a query parameter to the endpoint:http://localhost:3000/api/users?id=1. To read the query parameter passed to the endpoint, add a `request` parameter to the GET method.
const GET = async (request:any) => {
const response = await fetch('https://jsonplaceholder.typicode.com/users');
const responseData = await response.json();
return Response.json({"status":200, "data": responseData})
}
Next let's create a URL using the `url` from `request`.
typescript
const { searchParams } = new URL(request.url);
Once you have the `searchParams` you can get the expected query string parameter being passed.
typescript
const userId = searchParams.get('id');
Now let's try passing the `userId` along with the API endpoint URL to filter the API response as per the `id`.
Here is the modified GET method,
typescript
const GET = async (request:any) => {
const { searchParams } = new URL(request.url);
const userId = searchParams.get('id');
const response = await fetch(`https://jsonplaceholder.typicode.com/users?id=${userId}`);
const responseData = await response.json();
return Response.json({"status":200, "data": responseData})
}
Save the above changes and try to do a GET request by passing a query string as http://localhost:3000/api/users?id=1 and you will get the id-specific response.
Moving on, let's have a look at how to create a POST API endpoint.
POST API Endpoint
To create a POST API endpoint, you need to create another method called POST and export the method.
typescript
const POST = () => {
return Response.json({"status":200, "data": "Data updated successfully"});
}
export {POST}
Save the above changes and once you make a POST request to http://localhost:3000/api/users you'll get the following response,
json
{
"status": 200,
"data": "Data updated successfully"
}
While posting data to an endpoint you might be sending in some data to the API endpoint. Further, let's see how to read data posted to the POST API endpoint.
Inside the POST method, you can define a parameter called `request`. We'll be using the `request` parameter to read the data posted to the endpoint.
Doing `request.json()` would return the parameters passed in the body of the request. Let's use it to read the request body and return the data in response.
typescript
const POST = async (request: any) => {
const params = await request.json();
const name = params['name'];
return Response.json({"status":200, "data": "Data updated successfully", "name": name});
}
Save the above changes and try sending a POST request with `name` in the request body. The value of the `name` parameter will be returned in the response.
json
{
"status": 200,
"data": "Data updated successfully",
"name": "Roy"
}
Next, let's see how you can create an API endpoint for DELETE requests.
DELETE API Endpoint
Create a function called DELETE in the `app/api/users/route.ts` file and also export the function.
typescript
const DELETE = async (request:any) => {
return Response.json({status : 200, message : "Data deleted successfully"});
}
export {GET, POST, DELETE}
Now if you try to make a DELETE request to the API endpoint http://localhost:3000/api/users you will be able to get the following response,
{
"status": 200,
"message": "Data deleted successfully"
}
Passing data to the DELETE endpoint will be required. It can be either as a query string that we saw in the GET method or in the request body as we saw in the POST method.
Let's try passing in the body as we tried in the POST request. Here is how the modified DELETE method looks:
typescript
const DELETE = async (request:any) => {
const params = await request.json();
return Response.json({status : 200, message : "Data deleted successfully", params});
}
Now if you save the above code and hit the API endpoint with a DELETE request with some data in the request body, that data would be returned in the response.
So, when I hit the endpoint with the following JSON data,
json
{
"name": "Roy"
}
The response from the API is as shown,
json
{
"status": 200,
"message": "Data deleted successfully",
"params": {
"name": "Roy"
}
}
Similar to how we created API endpoints for GET, POST, and DELETE requests, endpoints for PUT, and PATCH requests can also be created.
Wrapping it up
In this tutorial, you learned how to create API endpoints in Next.js 14 using App routers.
You learned how to create an API that accepts GET, POST, and DELETE requests. You can further extend it to create requests for PATCH and PUT requests.
Jscrambler
The leader in client-side Web security. With Jscrambler, JavaScript applications become self-defensive and capable of detecting and blocking client-side attacks like Magecart.
View All ArticlesMust read next
Creating a Multi-Language Website with Next.js
As the online audience becomes increasingly diverse and global, the ability to communicate effectively in multiple languages has transformed into an essential requirement.
December 5, 2023 | By Ejiro Thankgod | 13 min read
How To Protect Next.js Apps with Jscrambler
In this article, we’ll look at how you can integrate Jscrambler into your Next.js app development workflow.
September 1, 2021 | By Jscrambler | 6 min read
Understanding Data Fetching in Next.js
In this tutorial, you'll learn how to fetch data in your Next.js application during SSR and client-side rendering.
April 11, 2023 | By Jay Raj | 7 min read