Published Mar 25, 2024 ⦁ 15 min read
Next.js API Router Essentials

Next.js API Router Essentials

Most web developers would agree that building API routes in Next.js can be tricky for beginners.

Luckily, by following some key principles and best practices, you can quickly get up and running with efficient and scalable API routes in your Next.js application.

In this comprehensive guide, you'll learn the fundamentals of Next.js's API routing capabilities, including how to set up basic routes, work with dynamic routes and parameters, integrate middlewares and helpers, and apply security measures.

Introduction to Next.js API Routing

Next.js API Routes provide a simple way to build serverless APIs and handle HTTP requests in a Next.js application. They allow you to create endpoints that act as serverless functions, without needing to manage a separate server.

Understanding Next.js API Routes

API Routes are functions that handle HTTP requests and responses. They are defined in the pages/api directory and look similar to page components, except they export a function handler instead of a React component.

When a request comes in to an API Route path, Next.js will invoke the function handler and pass the request and response objects. You can then process the request, query databases, call APIs, and send back responses, just like traditional server-side code.

Since API Routes run on Vercel's serverless platform, they provide automatic scaling and infrastructure management. You don't need to provision servers or manage infrastructure.

Advantages of Serverless API Routing in Next.js

There are several key benefits to using Next.js API Routes:

  • Simplicity - No need to setup and manage a separate API server. API Routes are co-located with your Next.js app code for easier development.

  • Scalability - Automatically scales to handle increasing traffic without provisioning servers.

  • Speed - Leverages serverless functions for fast response times.

  • Efficiency - Only runs when a request comes in, avoiding idle resources.

By handling APIs directly in Next.js, you can build fullstack apps faster with simplified infrastructure needs. API Routes unlock serverless development for Next.js apps.

Does Next.js have a router?

Next.js includes a built-in router that is based on the file system. Some key things to know about Next.js's routing:

File-System Based Routing

  • Routes are defined by files and folders in the pages directory
  • A file like pages/blog/first-post.js would map to the /blog/first-post route

Dynamic Routes

  • You can create dynamic route segments with square brackets like pages/blog/[slug].js
  • This would match routes like /blog/my-first-post dynamically

Built-in Support for API Routes

  • Next.js has first-class support for API routes under pages/api
  • This allows handling API requests directly without needing an external server

So in summary, Next.js provides a simple yet powerful router out of the box based on the file system structure. This handles client-side page routes, dynamic routes, and API routes.

Is Next.js good for API?

Next.js provides excellent support for building API endpoints with its API Routes feature. Here are some of the key benefits of using Next.js for APIs:

Simple and Fast Setup

  • Creating a new API route is as easy as creating a pages/api folder and adding handler files like pages/api/users.js.
  • The routing is handled automatically based on the filename.
  • No need to setup a separate server, Next.js handles that for you.

Full Power of Node.js

  • API Routes run on Vercel's serverless functions, powered by Node.js.
  • You have access to the entire Node.js ecosystem of modules and functionality.

Optimized for Production

  • Next.js handles caching, compression, HTTPS and more optimization automatically.
  • Minimal config needed, allowing you to focus on writing code.

Easy Deployment

  • Seamless deployment on Vercel's blazing fast global edge network.
  • Integrates with GitHub for continuous deployment.

TypeScript Support

  • Next.js has first-class support for TypeScript.
  • Strict typing for API functions helps reduce bugs.

So in summary - Next.js offers a fast, simple, and flexible way to create production-ready APIs. The development experience is excellent and deployment couldn't be easier. For most cases, it's an ideal choice for building APIs.

What is API router?

The Next.js API Router provides a straightforward way to handle server-side API routes in a Next.js application.

At a high level, the API Router allows you to:

  • Define routes and route handlers for API endpoints
  • Handle different HTTP methods like GET, POST, PUT, DELETE
  • Access request and response objects
  • Return JSON responses
  • Enable middleware and CORS

Some key benefits of using the API Router include:

  • Simple and familiar routing system - The API Router builds on Next.js's file-system based routing, so it feels familiar if you've used pages/ routing before.

  • Flexible functionality - You can build everything from simple CRUD APIs to complex GraphQL or REST endpoints. Lots of helper functions and middleware available.

  • Optimized performance - The router leverages Serverless Functions and automatic caching for fast response times.

  • Easy integration - Integrates seamlessly with existing Next.js universal app code. Easy to migrate existing server-side code.

  • Scalable - Scale APIs independently from frontend UI routes. The router scales automatically.

  • TypeScript support - Type definitions available for request, response objects.

Some examples of what you can build with API Router:

  • CRUD APIs for accessing/modifying data
  • Authentication/authorization endpoints
  • Database access/query APIs
  • GraphQL/REST API gateways
  • Webhook receivers
  • Automated background tasks
  • Dynamic content generation
  • Preview mode handlers

Overall, if you need to handle server-side routes in a Next.js app, the API Router takes care of the heavy lifting so you can focus on business logic.

How do I protect Next.js API routes from other browsers?

You can protect Next.js API routes from access by unauthorized browsers using the getServerSession() method.

Here is an example protected API route handler:

export default async function handler(req, res) {

  // Check for valid session
  const session = await getServerSession(req, res);

  if (!session) {
    return res.status(401).json({ message: 'Unauthorized request' });
  }

  // Session is valid, handle request
  res.status(200).json({ message: 'Authorized access' });

}

The key things to note:

  • Import getServerSession from next-auth/next
  • Call getServerSession() and check the response
    • If no valid session, return 401 Unauthorized
    • If session exists, user is authorized
  • Handle authorized request as needed

This checks for a valid user session on each request, preventing access if the session is invalid or missing.

Other tips:

  • Use middleware to handle session checks
  • Configure session lifetime, idle timeout
  • Revoke sessions on logout

So in summary, getServerSession() allows protecting API routes from unauthorized access by browsers without a valid user session. It integrates nicely with NextAuth.js for authentication.

sbb-itb-b2281d3

Setting Up Basic API Routes in Next.js

Next.js provides a simple way to create API endpoints directly within your application using API routes. API routes allow you to handle various HTTP methods and return responses, without needing an external server.

In this section, we'll walk through setting up basic API routes in Next.js step-by-step, using examples to illustrate key concepts.

Creating Your First API Route

To get started, create a pages/api directory if it doesn't already exist. Then, add a route.js or route.ts file. This will serve as your API route handler.

Here's an example pages/api/hello.js route that returns a JSON response:

export default function handler(req, res) {
  res.status(200).json({ text: 'Hello' })
}

The route handler takes in the request (req) and response (res) objects. We set the status to 200 and return a JSON response with a "Hello" text property.

Now this API route will be accessible at /api/hello in your Next.js app!

Handling Different HTTP Methods

Next.js API Routes support common HTTP methods like GET, POST, PUT, DELETE, and more.

You can check the method in the request object, and handle it appropriately:

export default function handler(req, res) {
  if (req.method === 'GET') {
    // handle GET request
  } else if (req.method === 'POST') {
    // handle POST request
  } else {
    // other methods
  }
}

This allows you to define what happens on different types of requests to the same endpoint.

Accessing Request Data and Parameters

The req object contains useful request data like query parameters, body content, headers, etc.

For example, to access a query parameter id:

export default function handler(req, res) {
  const { id } = req.query;
  // use id value in endpoint logic
}

And to access JSON body content:

import { NextRequest } from 'next/server'

export const config = {
  api: {
    bodyParser: true,
  },
}

export default async function handler(req: NextRequest) {
  const json = await req.json()
  // use json content
}

Sending HTTP Responses

The res object is used to send responses. You can set status codes and return JSON data:

export default function handler(req, res) {

  res.status(201).json({ data: 'Response data' })

} 

NextResponse.json() is a helper method that handles setting the JSON header and stringifying the data automatically.

This covers the basics of setting up and working with Next.js API Routes! With these building blocks, you can create robust API endpoints within your Next.js apps.

Advanced API Route Features

API Routes in Next.js provide developers with advanced capabilities to build robust backend functionality. By leveraging features like dynamic routing, middlewares, and helper functions, developers can create flexible and scalable APIs.

Implementing Dynamic API Routes

Dynamic routes enable the creation of parameterized API endpoints. By using square brackets [] around a segment in the filename, that part of the route becomes dynamic.

For example:

pages/api/users/[id].js

This /users/[id] route would match /users/1, /users/abc, etc. allowing you to access the id parameter in the route handler.

Dynamic routes unlock powerful capabilities:

  • Access URL parameters directly
  • Implement CRUD operations for data resources
  • Granularly manage cached data with next.revalidate

Overall, dynamic routes facilitate building scalable and customizable API endpoints.

Utilizing Middlewares and Helper Functions

Next.js provides helper functions like nextConnect() to implement middlewares. Middlewares execute logic before a request reaches the final route handler.

Common use cases for middlewares:

  • Handling CORS
  • Parsing request body
  • Authentication/authorization
  • Logging/analytics

Helper functions like nextConnect() simplify chaining middlewares. Overall, middlewares help manage cross-cutting concerns outside of route handlers.

Revalidating API Data

For dynamic routes, next.revalidate can programmatically revalidate cached data by triggering background regeneration.

This helps ensure users always receive fresh data from the API.

Key benefits of next.revalidate:

  • Refresh cached page/API data
  • Background regeneration without requests
  • Granular control over caching

With next.revalidate, developers can build fast yet real-time APIs.

Securing API Routes

To secure API routes, utilize:

  • Authentication - Allow access to authorized users only
  • CORS - Manage Cross-Origin Resource Sharing
  • Cookies - Persist data across sessions

Additionally, hosting Next.js apps under Custom Server allows modifying the Node.js request/response handling.

Overall, properly securing APIs ensures robust apps aligned to industry best practices.

Integrating API Routes with Next.js Features

API Routes provide a simple way to build API endpoints directly in Next.js. When combined with other Next.js features like getServerSideProps, Static Generation, and Preview Mode, API Routes open up new possibilities for building fast, flexible applications.

API Routes and getServerSideProps

Both API Routes and getServerSideProps allow server-side code execution in Next.js. The main difference is that getServerSideProps focuses on pre-rendering pages by fetching data, while API Routes are used for building REST APIs and handling forms/user input.

Some use cases where you may want to use one over the other:

  • Use getServerSideProps when you need to pre-render a page with data on each request. API Routes don't pre-render pages.
  • Use API Routes for handling user input like forms and mutations. getServerSideProps only runs on the initial request.
  • API Routes are useful for incrementally updating cached data with revalidate.

So in summary:

  • getServerSideProps - pre-render pages with data
  • API Routes - handle forms, user input, update cached data

They can be combined for some advanced use cases like submitting a form to update cached page data.

Migrating from getInitialProps to API Routes

getInitialProps was replaced by getServerSideProps and API Routes in Next.js 9. While code written with getInitialProps will continue to work, it's recommended to migrate to the newer APIs.

Some key differences:

  • getInitialProps ran on both server & client, while getServerSideProps and API Routes only run on server.
  • API Routes allow splitting code easier across files rather than everything in _app.js.
  • API Routes provide route handlers, middlewares, and revalidation.

To migrate:

  • Move data fetching code to getServerSideProps
  • Use API Routes for form input handling, cookies, headers, etc.
  • Split code across route files rather than _app.js

This takes advantage of the improved capabilities in Next.js while maintaining legacy app functionality.

Enhancing Static Generation with API Routes

API Routes complement Static Generation in Next.js by allowing incremental updates to cached data with revalidate.

After deploying a statically generated site, API Routes can dynamically:

  • Update related data - comments, views count, ratings etc
  • Handle user input like forms
  • Authentication, cookies, headers
  • Preview unpublished content

With SSG + API Routes you get the best of both worlds - fast static pages and dynamic functionality.

Leveraging Preview Mode with API Routes

The Preview Mode feature in Next.js allows viewing unpublished content before it goes live. API Routes provide flexibility in implementing preview functionality.

Some examples:

  • Use API Routes to handle preview session logic rather than all in getStaticProps.
  • Create a preview API Route to fetch and return draft content.
  • Use middlewares to check and validate preview sessions.

Overall, API Routes clean up preview implementations by separating concerns - session handling, draft content fetching, authentication etc can all be split into reusable route files.

In summary, API Routes integrate extremely well with Next.js for building fast, powerful applications with hybrid rendering models. They complement existing features while bringing improved organization, flexibility and capabilities for developers.

Real-World Examples of Next.js API Routes

Next.js API Routes provide a straightforward way to build server-side logic and RESTful APIs within a Next.js application. Here are some practical real-world examples of using API Routes in modern web apps.

Next.js 13 API Routes in Action

Next.js 13 introduced several enhancements to API Routes, including built-in support for CORS, easier dynamic route parameters, and middleware support. Here's an example leveraging these new capabilities:

export default async function handler(req, res) {
  // Access route parameters
  const {productId} = req.query 
  
  // Apply middleware
  await runMiddleware(req, res)

  // Handle CORS 
  res.setHeader('Access-Control-Allow-Origin', '*')

  // REST API logic
  const product = await fetchProduct(productId)

  return res.status(200).json(product)
}

This shows how Next.js 13 makes it simpler to build a REST API with dynamic routes, CORS headers, and middleware support.

Building a RESTful API with Next.js

This example creates a basic REST API for "products" with GET, POST, PUT, and DELETE routes:

// GET /api/products
export default async (req, res) => {
  const products = await fetchProducts()
  res.status(200).json(products)
}

// POST /api/products
export default async (req, res) => {
  const {name, description} = req.body
  const newProduct = await createProduct({name, description})
  res.status(201).json(newProduct)
} 

// PUT /api/products/:id
export default async (req, res) => {
  const {id} = req.query
  const {name, description} = req.body
  const updatedProduct = await updateProduct(id, {name, description}) 
  res.status(200).json(updatedProduct)
}

// DELETE /api/products/:id  
export default async (req, res) => {
  const {id} = req.query 
  await deleteProduct(id)
  res.status(204).end()
}

This demonstrates a common pattern for building CRUD APIs with Next's API Routes.

Integrating GraphQL with Next.js API Routes

We can also use API Routes to provide a GraphQL endpoint:

import { ApolloServer } from 'apollo-server-micro'
import { schema } from './schema'

const apolloServer = new ApolloServer({ schema })

export default apolloServer.createHandler({ path: '/api/graphql' })

Now we have a /api/graphql route that serves our GraphQL schema!

Handling Forms and Mutations

API Routes are useful for handling form submissions and data changes:

// POST /api/contacts
export default async (req, res) => {
  const { name, email } = req.body
  await createContact({ name, email }) 
  res.status(201).end() 
}

// PUT /api/contacts/:id 
export default async (req, res) => {
  const { id } = req.query
  const { name, email } = req.body

  const contact = await updateContact(id, { name, email })
  res.status(200).json(contact)
} 

We can reuse these handlers on the frontend to update our local state.

Writing Server-Side Code in API Routes

API Routes execute on the server, so we can access databases, microservices, etc:

import { connectToDatabase } from './db' 

export default async (req, res) => {
  const db = await connectToDatabase()
  const data = await db.fetch(...)
  
  return res.status(200).json(data)  
}

This allows building robust, server-side logic within our Next.js app!

Conclusion: Mastering Next.js API Routes

Next.js API Routes provide a straightforward way to build server-side APIs and logic in a Next.js application. As summarized in this guide, the key takeaways for working with Next.js API Routes include:

Essential Takeaways on Next.js API Routing

  • API Routes enable serverless functions and endpoints in Next.js apps
  • Simple to define routes, HTTP methods, request/response handlers
  • Powerful capabilities like dynamic routes, middlewares, revalidation
  • Integrates nicely with existing Next.js concepts like getServerSideProps
  • Enables full-stack apps - frontend + backend in one Next.js app

In summary, API Routes unlock backend capabilities directly within Next.js, streamlining full-stack development.

Expanding Your Next.js API Routing Skills

To further expand your skills with Next.js API Routes:

  • Explore advanced use cases like databases, authentication, GraphQL
  • Read the Next.js Documentation on API Routes
  • Check out API Routes examples in the Next.js GitHub Repo
  • Build your own apps using API Routes for CRUD operations
  • Learn how API Routes enable hybrid serverless apps on Vercel

With these resources and hands-on experience, you can master advanced API routing and unlock the full capabilities of Next.js.