[Next.js] server action vs route handlers

aken·2025년 2월 21일
0
post-thumbnail

들어가기 전에

route handler를 통해 폼 데이터에 있는 이미지를 서버에 추가하는 요청을 처리하였습니다. 근데 server action을 공식문서에서 처음 접하고, 이것으로도 폼 데이터를 처리할 수 있다는 걸 알게되었습니다. 그럼 '폼 데이터를 처리할 때, server action와 route handlers 중 어떤 걸 써야 할까? 어떤 차이가 있을까?' 궁금하게 되어 정리해봤습니다.

server action

server action 공식문서

nextjs 공식문서에는 server action을 다음과 같이 설명하고 있습니다.

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

server action은 서버에서 실행되는 비동기 함수입니다. 주로 폼을 제출하고 데이터를 변경하는데(mutation) 사용되고, 서버 컴포넌트와 클라이언트 컴포넌트에서 호출할 수 있습니다.

특징

  • 주로 폼을 제출하고 데이터를 변경하는데(mutation) 사용합니다.
  • server action은 POST 메서드만 사용하고, 다른 메서드는 사용하지 않습니다.
  • 서버 컴포넌트와 클라이언트 컴포넌트에서 호출할 수 있습니다.
  • server action은 함수라서 재사용할 수 있습니다.
  • <form>, 이벤트 핸들러, useEffect, third-party library, button 같은 폼 요소에서 사용 가능합니다.
  • server actions의 인수와 반환값은 React에 의해 직렬화할 수 있어야 합니다.

사용법

서버 컴포넌트
server action 함수 내부 최상단에 'use server'를 선언해줍니다.

export default function Page() {
  // Server Action
  async function create() {
    'use server'
    // 데이터 변조
  }
 
  return '...'
}

클라이언트 컴포넌트
server action을 둘 파일을 새로 생성하고, 그 파일 맨 위에 'use server'를 추가해주세요.

// app/actions
'use server'
 
export async function create() {}
// 클라이언트 컴폰넌트
'use client'
 
import { create } from '@/app/actions'
 
export function Button() {
  return <Button onClick={create} />
}

route handlers

route handlers 공식문서

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

route handlers로 라우트에 대한 요청 핸들러를 만들수 있습니다. 단, app router 환경에서만 사용 가능합니다.

특징

  • app router 환경에서만 사용 가능합니다.
  • 다양한 HTTP 메서드를 지원합니다.
  • Request, Response 객체를 사용합니다.
  • 공개 API 생성 가능합니다.

사용법

app 내에 폴더를 만들고 해당 폴더에 route.js 또는 route.ts 파일을 만들어두면 됩니다. 그럼 /api 경로로 요청하면 app/api/route.ts에 선언된 handler가 처리해줍니다.

// app/api/hello/route.ts

export async function GET() {
  return new Response('Hello, Next.js!', { status: 200 })
}

저는 주로 서버 컴포넌트일 경우 data fetching으로, 클라이언트 컴포넌트일 경우 useEffect을 이용하여 요청합니다.

// 서버 컴포넌트일 경우
export async function ServerComponent() {
  const response = await fetch(`${process.env.NEXT_PUBLIC_APP_URL}/api/hello`)
  const data = await response.json()
  
  // ...
}
// 클라이언트 컴포넌트일 경우
export function ClientComponent() {
  const [data, setData] = useState('')
  
  useEffect(() => {
    fetch(`${process.env.NEXT_PUBLIC_APP_URL}/api/hello`)
     .then(res => res.json())
     .then(result => setData(result))
  }, [])
  
  // ...
}

폼 데이터를 추가할 때, server action와 route handlers 중 어떤 걸 써야 할까?

HTML 요소를 캡쳐한 이미지를 생성하는 요청을 route handlers 방법으로도 만들어보고, server action으로도 만들어봤습니다.

직접 비교한 결과, server action을 사용하기로 결정했습니다.
이미지 파일이 포함된 FormData를 서버에 추가하는 단순한 요청이므로 server action로 선택했습니다.

route handlers를 선택하지 않은 이유는 다음과 같습니다.

  • RESTful endpoints를 만들 만큼 복잡한 로직이 아니었습니다.
  • 단순한 데이터 전송이면 충분한 요청이었습니다. 만약 세부적인 응답 처리가 필요하다면, server action은 한계가 있을 것 같습니다.
  • 외부에서 API 호출이 필요하지 않습니다.
  • Next.js 내부에서 호출하면 네트워크 창에 표시됩니다.

0개의 댓글