Skip to content

路由处理程序

¥Route Handlers

路由处理程序

¥Route Handlers

路由处理程序允许你使用 Web 请求响应 API 为给定路由创建自定义请求处理程序。

¥Route Handlers allow you to create custom request handlers for a given route using the Web Request and Response APIs.

需要了解:路由处理程序仅在 app 目录中可用。它们相当于 pages 目录中的 API 路由,这意味着你不需要同时使用 API 路由和路由处理程序。

¥Good to know: Route Handlers are only available inside the app directory. They are the equivalent of API Routes inside the pages directory meaning you do not need to use API Routes and Route Handlers together.

惯例

¥Convention

路由处理程序在 app 目录内的 route.js|ts file 中定义:

¥Route Handlers are defined in a route.js|ts file inside the app directory:

ts
export async function GET(request: Request) {}

路由处理程序可以嵌套在 app 目录内的任何位置,类似于 page.jslayout.js。但不能有 route.js 文件与 page.js 处于同一航段级别。

¥Route Handlers can be nested anywhere inside the app directory, similar to page.js and layout.js. But there cannot be a route.js file at the same route segment level as page.js.

支持的 HTTP 方法

¥Supported HTTP Methods

支持以下 HTTP 方法GETPOSTPUTPATCHDELETEHEADOPTIONS。如果调用不受支持的方法,Next.js 将返回 405 Method Not Allowed 响应。

¥The following HTTP methods are supported: GET, POST, PUT, PATCH, DELETE, HEAD, and OPTIONS. If an unsupported method is called, Next.js will return a 405 Method Not Allowed response.

扩展 NextRequestNextResponse API

¥Extended NextRequest and NextResponse APIs

除了支持原生 请求响应 API 之外,Next.js 还使用 NextRequestNextResponse 扩展了它们,为高级用例提供方便的辅助程序。

¥In addition to supporting the native Request and Response APIs, Next.js extends them with NextRequest and NextResponse to provide convenient helpers for advanced use cases.

缓存

¥Caching

默认情况下,路由处理程序不缓存。但是,你可以选择缓存 GET 方法。其他支持的 HTTP 方法不会被缓存。要缓存 GET 方法,请在路由处理程序文件中使用 路由配置选项(例如 export const dynamic = 'force-static')。

¥Route Handlers are not cached by default. You can, however, opt into caching for GET methods. Other supported HTTP methods are not cached. To cache a GET method, use a route config option such as export const dynamic = 'force-static' in your Route Handler file.

ts
export const dynamic = 'force-static'

export async function GET() {
  const res = await fetch('https://data.mongodb-api.com/...', {
    headers: {
      'Content-Type': 'application/json',
      'API-Key': process.env.DATA_API_KEY,
    },
  })
  const data = await res.json()

  return Response.json({ data })
}

需要了解:其他支持的 HTTP 方法不会被缓存,即使它们与缓存的 GET 方法放在同一个文件中。

¥Good to know: Other supported HTTP methods are not cached, even if they are placed alongside a GET method that is cached, in the same file.

使用缓存组件

¥With Cache Components

启用 缓存组件 后,GET 路由处理程序遵循与应用中普通 UI 路由相同的模型。它们默认在请求时运行,当不访问动态或运行时数据时可以预渲染,你可以使用 use cache 将动态数据包含在静态响应中。

¥When Cache Components is enabled, GET Route Handlers follow the same model as normal UI routes in your application. They run at request time by default, can be prerendered when they don't access dynamic or runtime data, and you can use use cache to include dynamic data in the static response.

静态示例 - 不访问动态或运行时数据,因此将在构建时进行预渲染:

¥Static example - doesn't access dynamic or runtime data, so it will be prerendered at build time:

tsx
export async function GET() {
  return Response.json({
    projectName: 'Next.js',
  })
}

动态示例 - 访问非确定性操作。在构建过程中,当调用 Math.random() 时,预渲染会停止,并延迟到请求时渲染。

¥Dynamic example - accesses non-deterministic operations. During the build, prerendering stops when Math.random() is called, deferring to request-time rendering:

tsx
export async function GET() {
  return Response.json({
    randomNumber: Math.random(),
  })
}

运行时数据示例 - 访问请求特定的数据。当调用运行时 API(例如 headers())时,预渲染将终止:

¥Runtime data example - accesses request-specific data. Prerendering terminates when runtime APIs like headers() are called:

tsx
import { headers } from 'next/headers'

export async function GET() {
  const headersList = await headers()
  const userAgent = headersList.get('user-agent')

  return Response.json({ userAgent })
}

需要了解:如果 GET 处理程序访问网络请求、数据库查询、异步文件系统操作、请求对象属性(例如 req.urlrequest.headersrequest.cookiesrequest.body)、运行时 API(例如 cookies()headers()connection())或非确定性操作,则预渲染会停止。

¥Good to know: Prerendering stops if the GET handler accesses network requests, database queries, async file system operations, request object properties (like req.url, request.headers, request.cookies, request.body), runtime APIs like cookies(), headers(), connection(), or non-deterministic operations.

缓存示例 - 访问动态数据(数据库查询),但使用 use cache 将其缓存,从而允许将其包含在预渲染的响应中:

¥Cached example - accesses dynamic data (database query) but caches it with use cache, allowing it to be included in the prerendered response:

tsx
import { cacheLife } from 'next/cache'

export async function GET() {
  const products = await getProducts()
  return Response.json(products)
}

async function getProducts() {
  'use cache'
  cacheLife('hours')

  return await db.query('SELECT * FROM products')
}

需要了解:use cache 不能直接在路由处理程序主体中使用;将其提取到一个辅助函数中。当新请求到达时,缓存的响应会根据 cacheLife 重新验证。

¥Good to know: use cache cannot be used directly inside a Route Handler body; extract it to a helper function. Cached responses revalidate according to cacheLife when a new request arrives.

特殊路由处理程序

¥Special Route Handlers

特殊路由处理程序(如 sitemap.tsopengraph-image.tsxicon.tsx)和其他 元数据文件 默认保持静态,除非它们使用动态 API 或动态配置选项。

¥Special Route Handlers like sitemap.ts, opengraph-image.tsx, and icon.tsx, and other metadata files remain static by default unless they use Dynamic APIs or dynamic config options.

路由解析

¥Route Resolution

你可以将 route 视为最底层的路由原语。

¥You can consider a route the lowest level routing primitive.

  • 它们不像 page 那样参与布局或客户端导航。

    ¥They do not participate in layouts or client-side navigations like page.

  • route.js 文件不能与 page.js 在同一路径上。

    ¥There cannot be a route.js file at the same route as page.js.

页面路由结果
app/page.jsapp/route.js冲突
app/page.jsapp/api/route.js有效
app/[user]/page.jsapp/api/route.js有效

每个 route.jspage.js 文件都会接管该路由的所有 HTTP 动词。

¥Each route.js or page.js file takes over all HTTP verbs for that route.

ts
export default function Page() {
  return <h1>Hello, Next.js!</h1>
}

// Conflict
// `app/route.ts`
export async function POST(request: Request) {}

了解更多关于路由处理程序 补充你的前端应用 的信息,或探索路由处理程序 API 参考

¥Read more about how Route Handlers complement your frontend application, or explore the Route Handlers API Reference.

路由上下文助手

¥Route Context Helper

在 TypeScript 中,你可以使用全局可用的 RouteContext 助手为路由处理程序键入 context 参数:

¥In TypeScript, you can type the context parameter for Route Handlers with the globally available RouteContext helper:

ts
import type { NextRequest } from 'next/server'

export async function GET(_req: NextRequest, ctx: RouteContext<'/users/[id]'>) {
  const { id } = await ctx.params
  return Response.json({ id })
}

很高兴知道

¥Good to know

  • 类型在 next devnext buildnext typegen 期间生成。

    ¥Types are generated during next dev, next build or next typegen.