How to use Next.js as a backend for your frontend Next.js

Next.js supports the Backend for Frontend (BFF) pattern, allowing you to create public endpoints that handle HTTP requests and return any content type. This article explains how to use Route Handlers, Proxy, and API Routes to build a secure and flexible backend layer for your frontend, including examples for data transformation, request validation, and content delivery.

Backend for FrontendRoute HandlerProxyNextRequestNextResponse

~3 دقیقه مطالعه · آخرین به‌روزرسانی ۴ آبان ۱۴۰۴

Introduction


Next.js supports the Backend for Frontend (BFF) pattern, allowing you to build public-facing endpoints that handle HTTP requests and return any content type—not just HTML. These endpoints can access external data sources, perform mutations, and serve as a lightweight API layer.


Getting Started


To scaffold a new project with backend capabilities:

npx create-next-app@latest --api

This includes an example route.ts file in the app/ directory.


Route Handlers


Route Handlers are public HTTP endpoints. You can define them using route.ts or route.js inside the app directory:

// app/api/route.ts
export function GET(request: Request) {
  return new Response('Hello from backend')
}

Error Handling


export async function POST(request: Request) {
  try {
    await submit(request)
    return new Response(null, { status: 204 })
  } catch (reason) {
    const message = reason instanceof Error ? reason.message : 'Unexpected error'
    return new Response(message, { status: 500 })
  }
}

Tip: Avoid exposing sensitive error messages to the client.


Serving Non-UI Content


Route Handlers can serve JSON, XML, images, files, and plain text. Common endpoint conventions include:

  • sitemap.xml
  • manifest.json
  • robots.txt
  • rss.xml

Example: serving an RSS feed:

// app/rss.xml/route.ts
export async function GET(request: Request) {
  const rssData = await fetchRSS()
  const rssFeed = `<rss>...</rss>`
  return new Response(rssFeed, {
    headers: { 'content-type': 'application/xml' },
  })
}

Reading Request Payloads


Use request.json(), request.formData(), or request.text() to read the body:

export async function POST(request: Request) {
  const data = await request.json()
  return Response.json({ data })
}

Validating Input


export async function POST(request: Request) {
  const formData = await request.formData()
  const email = formData.get('email')
  const contents = formData.get('contents')

  try {
    await validateInputs({ email, contents })
    const info = await sendMail({ email, contents })
    return Response.json({ messageId: info.messageId })
  } catch (reason) {
    return new Response('Error', { status: 500 })
  }
}

Cloning Requests


You can only read the request body once. Clone the request if needed:

const cloned = request.clone()
await cloned.body()

Data Transformation


Route Handlers can transform and aggregate data from multiple sources:

export async function POST(request: Request) {
  const body = await request.json()
  const params = new URLSearchParams({ lat: body.lat, lng: body.lng })
  const response = await fetch(`${weatherEndpoint}?${params}`)
  const raw = await response.text()
  const parsed = parseWeatherData(raw)
  return new Response(parsed, { status: 200 })
}

Proxying Requests


Use Route Handlers to proxy requests to external backends:

// app/api/[...slug]/route.ts
export async function POST(request: Request, { params }) {
  const isValid = await isValidRequest(request.clone())
  if (!isValid) return new Response(null, { status: 400 })

  const pathname = params.slug.join('/')
  const proxyURL = new URL(pathname, 'https://nextjs.org')
  const proxyRequest = new Request(proxyURL, request)
  return fetch(proxyRequest)
}

NextRequest and NextResponse


Next.js extends the Web APIs with NextRequest and NextResponse:

  • NextRequest: includes nextUrl for parsed pathname and query params
  • NextResponse: includes helpers like json(), redirect(), and rewrite()

export async function GET(request: NextRequest) {
  const url = request.nextUrl
  if (url.searchParams.get('redirect')) {
    return NextResponse.redirect(new URL('/', request.url))
  }
  return NextResponse.json({ pathname: url.pathname })
}

Conclusion


Next.js makes it easy to build a backend layer for your frontend. With Route Handlers, Proxy, and extended Web APIs, you can serve content, process data, and integrate with external systems—all within your app directory.


نوشته و پژوهش‌شده توسط دکتر شاهین صیامی

مقالات مرتبط

Advanced Client-Side Routing and Performance Hooks in Next.js

Next.js provides a rich set of client-side hooks and caching utilities that empower developers to build dynamic, responsive, and secure applications. From reading route parameters to tracking navigation state and reporting performance metrics, this guide walks you through the most important tools available in the App Router.

ادامه

Handling Authorization and Caching in Next.js: A Developer’s Guide

Next.js introduces powerful experimental features for access control and smart caching. This guide covers the unauthorized() function for custom 401 handling, unstable_cache for persistent memoization, updateTag for instant cache invalidation, and useLinkStatus for inline navigation feedback. Learn how to use these tools to build secure, performant, and responsive applications.

ادامه

redirect and refresh in Next.js — Smart Redirects and Client Refreshing via Server Actions

The redirect function in Next.js allows you to navigate users to a new route, returning either a 307 or 303 HTTP response depending on context. It works in Server Components, Client Components, Route Handlers, and Server Actions. The refresh function is used exclusively within Server Actions to refresh the client router. This article explains how both functions work, with practical examples and key considerations.

ادامه

NextRequest and NextResponse in Next.js — Managing Cookies, Headers, Redirects, and Rewrites

Next.js extends the native Web Request and Response APIs with NextRequest and NextResponse, offering powerful tools for managing cookies, headers, redirects, rewrites, and JSON responses. These utilities simplify server-side logic and improve control over routing, personalization, and security. This guide walks through their capabilities with practical examples and best practices.

ادامه

headers, ImageResponse, notFound, and permanentRedirect in Next.js — Request Handling, Dynamic Images, Errors, and Redirects

Next.js offers powerful tools for handling HTTP requests and responses in Server Components. The headers function lets you read incoming request headers. ImageResponse allows you to generate dynamic images using JSX and CSS. The notFound function renders a custom 404 page, and permanentRedirect enables permanent redirection to another route. This article explains how to use each feature with practical examples.

ادامه

A Complete Guide to Using metadata and generateMetadata in Next.js

In modern versions of Next.js, managing page metadata is more powerful and intuitive than ever. Metadata is automatically injected into the <head> of your pages and plays a vital role in SEO, social sharing, and user experience. This guide explains the two main ways to define metadata: using the static metadata object and the dynamic generateMetadata function.

ادامه