Simplest guide to Next.js APIs
Tags: api, nextjs, webdev, simple
Published: 2024-06-07 00:12:41

## What Makes Next.js APIs So Special?
I'm assuming you know what APIs are. APIs are an important part of developing functional web apps. Next.js has introduced the feature to create route handlers for APIs since version 9.0 in 2019. There are lots of ways to build a separate backend (like Ruby, PHP, Express.js, Django, etc.) other than Next.js, _**so why even do it in Next.js?**_.


##It might not be that great
By default, Next.js route handlers use serverless functions, which means in some cases you might have **cold starts**, **high cost for scaling**, and **vendor lock-in** since it requires serverless platforms like Vercel to work properly. It also has **limitations when it comes to using complex middleware,** unlike a library like Express.js, which was meant to be used for routing on a server. 

## But it's not that bad
But most of these issues are automatically taken care of by Vercel (which provides amazing **caching & optimization** strategies) and **serverless functions can be scalable and cost-effective** if done properly. Here are some more benefits of using Next.js as both your frontend and backend:
- **Hot reloading:** This means when developing, you get the same hot reload features as your frontend for your API routes, which makes development faster.
- **Consistency of your codebase:** It greatly simplifies development by keeping the frontend and backend logic in the same place.
- **File-based routing**: API routes use a simple file-based routing system that easily integrates into your Next.js project structure.
- **No additional setup:** There's no need to configure additional middleware or create a separate server. 
- **Simplication:** It has built-in features to simplify common tasks when developing your API.

#API routes in the Next.js app router
The app router uses a **file-based routing system** that starts from the `app` directory. You can **mirror URL paths by defining API routes in a nested folder structure**. By doing this, you create _Node.js serverless functions that act as API endpoints_.

```
app/
└── api/
    └── hello/
        └── route.js
```

##Creating API routes
The API route file is usually named `route.js` or `route.ts` (for TypeScript users). This has to be in an `api` folder in the `app` folder. You can define **functions in the `route.js` files that handle different HTTP methods** (such as GET, POST, PUT, PATCH, etc.). For example, when you can make a `GET` request to `/api/hello` it would be handled by a `GET` function in `app/api/hello/route.js`.

### Request methods and API route functions
The standard convention is that within the `route.js` or `route.ts` file, you name an exported function with the **HTTP method you want it to handle in your API endpoint in uppercase**. The functions usually look like this: 

```
// app/api/users/route.js

export async function GET(request) {
  // Simulate a database call to fetch users
  const users = [
    { id: 1, name: 'John Doe' },
    { id: 2, name: 'Jane Doe' },
  ];

  // Return the users as a JSON response
  return NextResponse.json(users);
}

```

### NextResponse and Request

The `NextResponse` is a **helper class** that extends the [web Response API](https://developer.mozilla.org/en-US/docs/Web/API/Response) with **additional convenience methods**, which are used to create responses. You can use it to rewrite, redirect, set headers, or create and send JSON responses.

---
The `Request`: When you define functions by using HTTP methods in creating your API endpoints, **the functions receive a `Request` object as an argument** which contains information about the incoming request. The object uses the [web Request API](https://developer.mozilla.org/en-US/docs/Web/API/Request). You can use it to read the request query parameters, **read the request body**, or access the request headers.

##Dynamic routes
By using **square brackets**, when naming your folders before the `route.ts` or `route.js` file, you can create a dynamic route for your API. 
```
app/
  └── api/
      └── users/
          └── [userId]/
              └── route.ts
```
### Accessing a dynamic route
The dynamic route parameters can be accessed from the **route handler function's second argument**, which has the `params` object.
Take a look at this example: 

```
// app/api/users/[userId]/route.ts

export async function GET(request: Request, { params }: { params: { userId: string }}) {
const {userId} = params

  // Simulate a database call to fetch users
  const users = [
    { id: 1, name: 'John Doe' },
    { id: 2, name: 'Jane Doe' },
  ];

  //filter user by id
  const user = users.filter((user) => user.id == userId)

  // Return the users as a JSON response
  return NextResponse.json(user);
}
```
I hope that wasn't complicated, and you got something out of this.
You can hear more from me on:
[Twitter (X)](https://x.com/code_withjoseph) | [Instagram](https://www.instagram.com/codewithjosephwebdev)