Next.js 13引入了一个新特性:Route Handlers。

这个特性为我们提供了一种在App Router中创建API端点的新方式。

如果你觉得自己已经很熟悉Next.js的API路由了,那么这篇文章可能会给你一些新的见解。

Route Handlers:Next.js API的新时代

Route Handlers是Next.js在app目录中处理API请求的方式。

它们使用了Web Request和Response APIs,这意味着你可以使用标准的Web API来处理请求和响应。

基本用法

在app目录中创建一个route.js(或route.ts)文件就可以定义一个Route Handler。例如:

  1. // app/api/hello/route.ts
  2. export async function GET(request: Request) {
  3. return new Response('Hello, Next.js!')
  4. }

这个简单的例子创建了一个响应GET请求的API端点。

支持的HTTP方法

Route Handlers支持所有主要的HTTP方法:GET, POST, PUT, PATCH, DELETE, HEAD, 和 OPTIONS。例如:

  1. export async function GET(request: Request) {
  2. // 处理GET请求
  3. }
  4. export async function POST(request: Request) {
  5. // 处理POST请求
  6. }
  7. // 其他方法类似...

高级用法

1. 动态路由

Route Handlers支持动态路由,这让我们可以创建更灵活的API:

  1. // app/api/user/[id]/route.ts
  2. export async function GET(
  3. request: Request,
  4. { params }: { params: { id: string } }
  5. ) {
  6. const id = params.id
  7. // 使用id获取用户数据
  8. return new Response(`User id: ${id}`)
  9. }

另外一个例子,可以获得嵌套参数:

  1. export async function GET(
  2. request: Request,
  3. { params }: { params: { slug: string } }
  4. ) {
  5. const slug = params.slug // 'a', 'b', or 'c'
  6. }

在官方文档上提到:

你真的知道Nextjs的api怎么用吗? - 图1

2. 查询参数处理

Next.js提供了便捷的方法来处理查询参数:

  1. import { type NextRequest } from 'next/server'
  2. export function GET(request: NextRequest) {
  3. const searchParams = request.nextUrl.searchParams
  4. const query = searchParams.get('query')
  5. // 处理查询参数
  6. }

3. 响应流

Route Handlers支持流式响应,这在处理大量数据或长时间运行的操作时非常有用:

  1. function iteratorToStream(iterator) {
  2. return new ReadableStream({
  3. async pull(controller) {
  4. const { value, done } = await iterator.next()
  5. if (done) {
  6. controller.close()
  7. } else {
  8. controller.enqueue(value)
  9. }
  10. },
  11. })
  12. }
  13. export async function GET() {
  14. const iterator = async function* () {
  15. yield 'Hello'
  16. await new Promise(resolve => setTimeout(resolve, 1000))
  17. yield 'World'
  18. }()
  19. const stream = iteratorToStream(iterator)
  20. return new Response(stream)
  21. }

4. CORS处理

你可以直接在Route Handler中设置CORS头:

  1. export async function GET(request: Request) {
  2. return new Response('Hello, Next.js!', {
  3. status: 200,
  4. headers: {
  5. 'Access-Control-Allow-Origin': '*',
  6. 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
  7. 'Access-Control-Allow-Headers': 'Content-Type, Authorization',
  8. },
  9. })
  10. }

5.文件上传

处理文件上传变得更加简单:

  1. export async function POST(request: Request) {
  2. const formData = await request.formData()
  3. const file = formData.get('file')
  4. // 处理文件上传
  5. }

6.性能优化

Route Handlers默认是动态的,但你可以通过配置使它们变为静态:

  1. export const dynamic = 'force-static'
  2. export async function GET() {
  3. // 这个处理器会被静态生成
  4. }

route.js

在我们深入探讨 Route Handlers 的各种用法之后,让我们特别关注一下 route.js 文件本身。

这个特殊的文件在 Next.js 的 App Router 中扮演着关键角色,它不仅定义了 API 路由,还控制着路由的行为和性能特性。

route.js 的特殊性

route.js 是 Next.js 中的一个特殊文件,它专门用于创建 API 路由。与 page.js 不同,route.js 不会渲染 UI,而是专注于处理 HTTP 请求和响应。

重要的是要注意,在同一个路由段级别上,route.jspage.js 不能共存。

这是因为 Next.js 需要明确知道应该如何处理对该路由的请求 —— 是渲染一个页面还是处理一个 API 请求。

文件命名和位置

route.js (或 route.ts 对于 TypeScript 项目)可以放置在 app 目录的任何嵌套层级中。例如:

  • app/api/route.js
  • app/dashboard/api/route.js
  • app/users/[id]/route.js

配置选项

route.js 文件支持多种配置选项,这些选项可以影响路由的行为和性能。以下是一些重要的配置选项:

  1. export const dynamic = 'auto'
  2. export const dynamicParams = true
  3. export const revalidate = false
  4. export const fetchCache = 'auto'
  5. export const runtime = 'nodejs'
  6. export const preferredRegion = 'auto'

让我们逐一解释这些选项:

  1. dynamic:控制路由的动态行为。可以设置为 ‘auto’、’force-dynamic’ 或 ‘force-static’。
  2. dynamicParams:决定是否允许动态参数。
  3. revalidate:设置重新验证的时间间隔(以秒为单位)。
  4. fetchCache:控制 fetch 请求的缓存行为。
  5. runtime:指定运行时环境,可以是 ‘nodejs’ 或 ‘edge’。
  6. preferredRegion:指定首选的部署区域。

示例:配置静态路由

如果你想创建一个静态生成的 API 路由,可以这样配置:

  1. // app/api/static-data/route.ts
  2. export const dynamic = 'force-static'
  3. export async function GET() {
  4. const data = await fetchSomeData()
  5. return Response.json(data)
  6. }

这个配置会使 Next.js 在构建时生成这个 API 路由的响应,而不是在每次请求时动态生成。

注意事项

  1. 路由冲突:确保在同一路径下不会同时存在 route.jspage.js
  2. HTTP 方法:只有你在 route.js 中明确定义的 HTTP 方法才会被处理。未定义的方法会返回 405 Method Not Allowed。
  3. TypeScript 支持:使用 TypeScript 时,你可以利用类型系统来增强代码的可靠性和可维护性。

最佳实践

  1. 合理使用静态生成:对于不经常变化的数据,使用静态生成可以显著提高性能。
  2. 适当设置缓存:根据你的数据更新频率,合理设置 revalidate 选项。
  3. 选择正确的运行时:根据你的需求选择 Node.js 或 Edge 运行时。Edge 运行时通常具有更低的冷启动时间,适合需要快速响应的场景。
  4. 利用动态导入:对于大型依赖,可以使用动态导入来优化加载时间。

希望这篇文章能帮助你更好地理解和使用Next.js的Route Handlers。Happy coding!