本文首先会简单说明一下 Next.js 中的 Route Handlers 和 Server Action 是什么,然后再对比它们之间的区别,以及什么时候使用 Route Handlers,什么时候使用 Server Action。

Router Handlers 是什么?

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

在 Next.js 中,Route Handlers 允许你使用 Web 请求和响应 API,为给定的路由创建自定义请求处理程序。Route Handlers 只能在 app 目录中定义,等同 Pages Router 中在 pages 目录中的 API Routes

下面的示例代码定义了 Router Handlers:

// app/api/route.js
export async function GET(request) {
  return new Response(JSON.stringify({ message: 'Hello, world!' }), {
    status: 200,
    headers: {
      'Content-Type': 'application/json'
    }
  });
}

export async function POST(request) {
  const data = await request.json();
  return new Response(JSON.stringify({ message: 'Data received', data }), {
    status: 201,
    headers: {
      'Content-Type': 'application/json'
    }
  });
}
  • 当请求 GET /api 时,会返回 {"message":"Hello, world!"},状态码为 200
  • 当请求 POST /api 时,会返回 {"message":"Data received", "data": ...},状态码为 201

Server Action 是什么?

Server Actions are asynchronous functions that are executed on the server. They can be used in Server and Client Components to handle form submissions and data mutations in Next.js applications.

Server Actions 是在服务器上执行的异步函数。它们可以在 Next.js 应用程序中的 Server 和 Client 组件中使用,用于处理表单提交和数据变更。

Server Components

在 Server Components 中,可以在函数或模块级声明 "use server" 指令来定义 Server Action。

如下代码在函数体中声明 "use server" 指令定义了一个 Server Action:

// Server Component
export default function Page() {
  // Server Action
  async function create() {
    'use server'
 
    // ...
  }
 
  return (
    // ...
  )
}

Client Components

在 Client Components 中,则只能导入在模块级定义的 Server Action:

// app/actions.js
'use server'
 
export async function create() {
  // ...
}

// app/ui/button
import { create } from '@/app/actions'

export function Button() {
    return (
        // ...
    )
}

或者也可以传递 Server Action 作为 props:

<ClientComponent updateItem={updateItem} />
// app/client-component
'use client'

export default function ClientComponent({ updateItem }) {
    return <form action={updateItem}>{/* ... */}</form>
}

两者的区别

Server Actions 和 Route Handlers 都在服务端运行。Route Handlers 是低等级的抽象,可以用来实现 RESTful API、GraphQL API 或者其他任何类型的 API。而 Server Actions 是更高等级的抽象,更适合在服务端处理数据变更。

实际上 Server Actions 是依靠当前页面路由的 POST 请求来触发的,而 Route Handlers 可以处理任何类型的请求,包括 GETPOSTPUTDELETE 等。

如果我们编写的接口需要被外部系统调用,那么就应该使用 Route Handlers,如果只是相对简单的数据变更和获取,那么使用 Server Actions 要更方便一些。

再说一个题外话: 在 Server Component 中也可以使用 fetch 获取数据,这有点类似 Route Handlers。但不同的是,Server Component 是在客户端渲染之前执行的,不具备 Route Handlers 那样的响应格式和请求处理灵活性。

参考链接