DEV Community

Turing
Turing

Posted on

Nextjs API Router

How to Use the Next.js API Router in Next.js with TypeScript

Next.js is a powerful framework that simplifies both front-end and back-end development by allowing you to build APIs directly in your application using its API Router feature. When combined with TypeScript, it offers the added benefit of type safety and improved developer experience. In this article, we will explore how to use the Next.js API Router with TypeScript, highlighting the best practices for building type-safe and scalable APIs.

What is the Next.js API Router?
The Next.js API Router enables you to create server-side API endpoints in the same project as your Next.js app. These endpoints can handle requests, interact with databases, and return JSON responses, making it easy to build full-stack applications. Each API route corresponds to a file in the pages/api or app/api directory (in newer Next.js versions using the app directory).

Setting Up a Next.js API Router with TypeScript
Let’s walk through how to create a basic API using the Next.js API Router with TypeScript.

Step 1: Initialize a Next.js Project with TypeScript
If you haven’t already, start by creating a Next.js project with TypeScript:

Want to learn nextjs? try gpteach.us - AI pitching you code to practice nextjs and typescript with react.

npx create-next-app@latest my-nextjs-app --typescript

Enter fullscreen mode Exit fullscreen mode

This command will set up a new Next.js project with TypeScript pre-configured.

Step 2: Create an API Route
To create a new API route, you can add a file to the app/api or pages/api directory, depending on your Next.js version. For this example, we will create a simple API route to fetch user data.

Create a file called app/api/users/route.ts:

// app/api/users/route.ts

import { NextResponse } from 'next/server';

type User = {
  id: number;
  name: string;
  email: string;
};

const users: User[] = [
  { id: 1, name: 'John Doe', email: 'john@example.com' },
  { id: 2, name: 'Jane Smith', email: 'jane@example.com' },
];

export async function GET() {
  return NextResponse.json(users);
}

Enter fullscreen mode Exit fullscreen mode

Here’s what’s happening:

The file defines a GET request handler using TypeScript.
The handler returns a JSON response using NextResponse.json().
The User type is used to ensure that the structure of the data is correctly typed.
This file corresponds to the API route /api/users. When a GET request is made to /api/users, the server responds with a JSON array of users.

Step 3: Type Definitions for API Handlers
Type safety is crucial when working with TypeScript, especially for APIs. In the above example, we used a custom User type to ensure that the response has the correct shape. You can go a step further and define types for request and response objects.

For example, let’s create a new API route for creating a user with a POST request.

// app/api/users/route.ts

import { NextRequest, NextResponse } from 'next/server';

type User = {
  id: number;
  name: string;
  email: string;
};

let users: User[] = [
  { id: 1, name: 'John Doe', email: 'john@example.com' },
  { id: 2, name: 'Jane Smith', email: 'jane@example.com' },
];

export async function GET() {
  return NextResponse.json(users);
}

export async function POST(req: NextRequest) {
  try {
    const { name, email }: Partial<User> = await req.json();

    if (!name || !email) {
      return NextResponse.json({ error: 'Name and email are required' }, { status: 400 });
    }

    const newUser: User = {
      id: users.length + 1,
      name,
      email,
    };

    users.push(newUser);
    return NextResponse.json(newUser, { status: 201 });
  } catch (error) {
    return NextResponse.json({ error: 'Invalid request data' }, { status: 400 });
  }
}

Enter fullscreen mode Exit fullscreen mode

We define a POST request handler that extracts name and email from the request body.
The request is validated to ensure that both name and email are provided.
A new user is added to the users array and returned with a 201 status.
The request is type-checked, ensuring that TypeScript catches any type-related issues during development.

Using Middleware with the Next.js API Router
Another advantage of the Next.js API Router is the ability to add middleware for tasks such as authentication, logging, or validation. For example, let’s create a simple middleware to log incoming requests.

// app/middleware.ts

import { NextRequest, NextResponse } from 'next/server';

export function middleware(req: NextRequest) {
  console.log(`Request made to: ${req.url}`);
  return NextResponse.next();
}

Enter fullscreen mode Exit fullscreen mode

This middleware will be applied globally to all API routes, making it easy to log or modify requests before they hit the route handler.

Error Handling in Next.js API Router
When building APIs, it’s important to handle errors gracefully. In Next.js, you can return error responses using the NextResponse object. Here’s how to handle different error cases:

// app/api/users/route.ts

import { NextRequest, NextResponse } from 'next/server';

export async function GET(req: NextRequest) {
  try {
    // Simulate fetching users from a database
    if (!users) {
      throw new Error('No users found');
    }

    return NextResponse.json(users);
  } catch (error) {
    return NextResponse.json({ error: error.message }, { status: 500 });
  }
}

Enter fullscreen mode Exit fullscreen mode

In this example, if no users are found, the API will return a 500 status code with an error message.

Why Use Next.js API Router with TypeScript?
Using the Next.js API Router with TypeScript offers several benefits:

Type Safety: By using TypeScript, you reduce the chances of runtime errors due to incorrect data types.
Improved Developer Experience: TypeScript provides auto-completion, intelligent code navigation, and error checking in your IDE.
Scalability: With the modular nature of Next.js API Router, it’s easy to build scalable APIs within your Next.js app.
Seamless Integration: Both front-end and back-end logic can reside within the same Next.js project, simplifying full-stack development.

Conclusion

The Next.js API Router makes it incredibly easy to create server-side API routes in your Next.js applications. When combined with TypeScript, you get type safety, improved maintainability, and a better overall development experience. By using the API Router, you can handle complex server-side logic without leaving your Next.js project.

Whether you’re fetching data from a database or handling user authentication, the Next.js API Router with TypeScript offers a flexible and powerful solution for building APIs.

Top comments (0)