Server Actions는 Next.js 13에서 도입된 새로운 기능으로, 서버에서 직접 실행되는 비동기 함수이다.
기존에는 데이터 가져오기(fetching)와 데이터 변경(mutation)을 위해 API 라우트를 설정하고, 클라이언트 컴포넌트에서 이를 호출하는 방식이 일반적이었다. 이 방식에서 클라이언트가 서버로 데이터를 요청할 때마다 별도의 네트워크 통신이 발생하고 API 요청 및 응답 처리를 위한 추가 코드가 필요했다.
정리하자면, 기존에는 서버 컴포넌트에서 fetching(데이터 읽기) 작업만 수행할 수 있었고, 데이터 변경 작업은 클라이언트 컴포넌트에서 처리해야 했다.만약 데이터를 변경하려면, 클라이언트 컴포넌트에서 API 요청을 만들어 서버로 데이터를 전송한 뒤, 서버에서 해당 요청을 처리하고 결과를 다시 클라이언트로 반환하는 과정을 거쳤다. 이 과정에서 매번 클라이언트-서버 간의 네트워크 요청이 발생했으며 코드도 API 주소를 지정해줘야 했다.
하지만 Server Actions는 이 과정을 간소화하여 API 라우팅 없이 서버에서 직접 함수 실행이 가능하다.
이를 통해 클라이언트와 서버 간의 별도 네트워크 요청 없이 데이터를 처리할 수 있으며, 더욱 직관적이고 효율적인 데이터 가져오기 및 수정이 가능하다.
Server Actions는 서버 컴포넌트와 클라이언트 컴포넌트 모두에서 호출할 수 있다.
클라이언트 코드에서 불필요한 API 요청 로직을 제거하고 서버 측에서 직접 데이터를 관리할 수 있다.
💡 Server Actions 주요 특징
네트워크 요청 최소화 : 클라이언트-서버 간 불필요한 네트워크 요청 감소
직관적인 데이터 수정 : API 라우터 없이 서버 측에서 데이터를 직접 수정 가능
❓Server Actions 어떤 상황에서 사용하는 것이 좋을까?
사용자 입력을 서버에 전달하고 데이터를 수정해야 하는 폼 제출 작업
서버에서 데이터 수정/삭제 작업을 수행할 때
클라이언트 코드 간소화를 위해 서버 측에서 직접 실행 가능한 함수를 호출해야 할 때
02. Server Component에서 Server Actions 사용
서버 컴포넌트는 서버에서 렌더링되므로 서버 측 데이터를 직접 가져오거나 처리하는 데 유용하다.
전통적으로 서버 컴포넌트에서 데이터 패칭은 fetch()를 통해 이루어졌다. 그러나 데이터 변경 작업(데이터베이스 업데이트, 리소스 생성 등)을 처리하려면 클라이언트 컴포넌트와의 상호작용 및 별도의 API 라우터 설정이 필요했다.
Server Actions는 이러한 번거로움을 줄이고 서버 컴포넌트 내에서 데이터 변경 작업을 쉽게 수행할 수 있도록 지원한다.
서버 컴포넌트에서 Server Actions를 사용하는 방법은 다음과 같다.
함수 본문의 맨 위에 “use server”를 사용하여 비동기 함수를 정의하여 server actions를 작성한다.
아래는 서버 컴포넌트에서 Server Actions를 사용하여 데이터베이스에 새로운 아이템을 생성하는 예시이다.
// app/page.tsx
export default function Page() {
// Server Action 정의
async function createItem(data: { name: string }) {
'use server';
// 데이터베이스에 새로운 아이템 추가
await db.items.create({ data: { name: data.name } });
console.log("Item created on the server");
}
// 폼을 서버 컴포넌트 내에서 직접 처리
return (
<form action={createItem}>
<input name="name" type="text" placeholder="Enter item name" required />
<button type="submit">Create Item</button>
</form>
);
}
서버 컴포넌트에서 Server Actions를 사용하면 서버 내부에서 실행되기 때문에 네트워크 통신이 없다. 또한 서버에서 바로 실행되므로 클라이언트-서버 요청/응답 대기 시간이 없다. 클라이언트에서는 Server Action의 내부 구현이 보이지 않아 보안 측면에서 유리하다.
03. Client Component에서 Server Actions 사용
#1. 클라이언트 컴포넌트에서 Server Actions
Server Actions는 클라이언트와 서버 간의 인터랙션을 보다 효율적으로 처리할 수 있도록 한다.
클라이언트 컴포넌트에서 직접 API를 호출하지 않고 서버에서 실행되는 함수를 클라이언트에서 바로 호출할 수 있다.
클라이언트 컴포넌트에서 Server Actions를 사용하는 이유는 다음과 같다.
◼︎ API 라우트 설정의 불필요성
기존의 방식에서는 클라이언트가 서버로 데이터를 보내기 위해 API 엔드포인트를 만들어야 했다.
이때 API 라우트를 별도로 설정하고, HTTP 클라이언트를 사용하여 요청을 보내는 과정이 필요했다.
하지만, Server Actions를 사용하면 이러한 과정이 필요하지 않다.
클라이언트에서 서버의 함수를 직접 호출하는 것마으로 데이터를 처리할 수 있다.
◼︎ 네트워크 요청 단순화
Server Actions를 사용하면 클라이언트에서 fetch나 axios와 같은 HTTP 요청을 작성할 필요가 없다.
대신 클라이언트에서 서버 함수를 호출하면, 서버에서 해당 작업을 처리하고 결과를 바로 반환받는다.
이는 클라이언트와 서버 간의 직접적인 네트워크 요청을 없애고 코드 구조 또한 단순화시킨다.
다음으로 클라이언트 컴포넌트에서 API를 직접 호출하여 서버 데이터를 호출하거나 수정했을 때와 Server Actions로 처리했을 때 코드 예시를 보며 두 방식의 차이점을 명확히 알아보겠다.
#2. 클라이언트 컴포넌트에서 API 호출 vs Server Actions
🎯 기존 클라이언트 컴포넌트에서 API를 이용해 데이터를 변경하는 경우
클라이언트 컴포넌트에서 데이터를 변경하려면 보통 API 엔드포인트(/api/endpoint)를 호출해야 한다.
반면 Server Action을 사용하면 API 라우트를 별도로 생성할 필요 없이 서버 함수가 바로 호출된다.
즉, 클라이언트에서 직접 fetch를 작성할 필요 없이 단순히 함수를 호출하는 형태로 네트워크 요청을 수행할 수 있다.
// Server Actions
'use server';
export async function createItem(data: { name: string }) {
if (!data.name) throw new Error("Name is required");
// DB 작업
}
// 클라이언트 컴포넌트에서 Server Actions 사용
'use client';
import { createItem } from '@/app/actions';
export default function Button() {
const handleClick = async () => {
await createItem({ name: 'Item' });
console.log('Item created');
};
return <button onClick={handleClick}>Create Item</button>;
}
다음으로 클라이언트 컴포넌트에서 Server Actions를 작성하는 방법에 대해 더 자세히 다루고자 한다.
#3. 클라이언트 컴포넌트에서 Server Actions 사용 방법
클라이언트 컴포넌트내에서 직접 Server action 함수 작성은 불가능하다.
다음과 같이 module로 작성된 서버 액션 함수를 import 하여 사용해야 한다.
1️⃣ Server Actions 정의하기
먼저 Server Action을 정의할 파일에 “use server”지시어를 추가하여 서버에서 실행될 함수를 작성한다.
이 함수는 서버에서 실행되며 클라이언트에서 호출할 수 있다.
// app/actions.ts
'use server'
export async function createUser(formData: FormData) {
// 서버에서 폼 데이터 처리 및 검증
const email = formData.get('email');
if (!email) {
return { error: '이메일을 입력해 주세요.' };
}
// 데이터 처리 (예: DB에 저장)
return { success: true };
}
2️⃣ 클라이언트 컴포넌트에서 Server Actions 호출하기
클라이언트 컴포넌트에서 위에서 생성한 createUser와 같은 Server Action을 호출하려면 해당 Server Action이 정의된 파일을 import하여 클라이언트에서 이를 호출한다.
[Next.js] Server Actions & Mutations : use server
01. Server Actions란?
Server Actions는 Next.js 13에서 도입된 새로운 기능으로, 서버에서 직접 실행되는 비동기 함수이다.
기존에는 데이터 가져오기(fetching)와 데이터 변경(mutation)을 위해 API 라우트를 설정하고, 클라이언트 컴포넌트에서 이를 호출하는 방식이 일반적이었다. 이 방식에서 클라이언트가 서버로 데이터를 요청할 때마다 별도의 네트워크 통신이 발생하고 API 요청 및 응답 처리를 위한 추가 코드가 필요했다.
하지만 Server Actions는 이 과정을 간소화하여 API 라우팅 없이 서버에서 직접 함수 실행이 가능하다.
이를 통해 클라이언트와 서버 간의 별도 네트워크 요청 없이 데이터를 처리할 수 있으며, 더욱 직관적이고 효율적인 데이터 가져오기 및 수정이 가능하다.
Server Actions는 서버 컴포넌트와 클라이언트 컴포넌트 모두에서 호출할 수 있다.
클라이언트 코드에서 불필요한 API 요청 로직을 제거하고 서버 측에서 직접 데이터를 관리할 수 있다.
💡 Server Actions 주요 특징
❓Server Actions 어떤 상황에서 사용하는 것이 좋을까?
02. Server Component에서 Server Actions 사용
서버 컴포넌트는 서버에서 렌더링되므로 서버 측 데이터를 직접 가져오거나 처리하는 데 유용하다.
전통적으로 서버 컴포넌트에서 데이터 패칭은 fetch()를 통해 이루어졌다. 그러나 데이터 변경 작업(데이터베이스 업데이트, 리소스 생성 등)을 처리하려면 클라이언트 컴포넌트와의 상호작용 및 별도의 API 라우터 설정이 필요했다.
Server Actions는 이러한 번거로움을 줄이고 서버 컴포넌트 내에서 데이터 변경 작업을 쉽게 수행할 수 있도록 지원한다.
서버 컴포넌트에서 Server Actions를 사용하는 방법은 다음과 같다.
함수 본문의 맨 위에 “use server”를 사용하여 비동기 함수를 정의하여 server actions를 작성한다.
아래는 서버 컴포넌트에서 Server Actions를 사용하여 데이터베이스에 새로운 아이템을 생성하는 예시이다.
서버 컴포넌트에서 Server Actions를 사용하면 서버 내부에서 실행되기 때문에 네트워크 통신이 없다. 또한 서버에서 바로 실행되므로 클라이언트-서버 요청/응답 대기 시간이 없다. 클라이언트에서는 Server Action의 내부 구현이 보이지 않아 보안 측면에서 유리하다.
03. Client Component에서 Server Actions 사용
#1. 클라이언트 컴포넌트에서 Server Actions
Server Actions는 클라이언트와 서버 간의 인터랙션을 보다 효율적으로 처리할 수 있도록 한다.
클라이언트 컴포넌트에서 직접 API를 호출하지 않고 서버에서 실행되는 함수를 클라이언트에서 바로 호출할 수 있다.
클라이언트 컴포넌트에서 Server Actions를 사용하는 이유는 다음과 같다.
◼︎ API 라우트 설정의 불필요성
기존의 방식에서는 클라이언트가 서버로 데이터를 보내기 위해 API 엔드포인트를 만들어야 했다.
이때 API 라우트를 별도로 설정하고, HTTP 클라이언트를 사용하여 요청을 보내는 과정이 필요했다.
하지만, Server Actions를 사용하면 이러한 과정이 필요하지 않다.
클라이언트에서 서버의 함수를 직접 호출하는 것마으로 데이터를 처리할 수 있다.
◼︎ 네트워크 요청 단순화
Server Actions를 사용하면 클라이언트에서 fetch나 axios와 같은 HTTP 요청을 작성할 필요가 없다.
대신 클라이언트에서 서버 함수를 호출하면, 서버에서 해당 작업을 처리하고 결과를 바로 반환받는다.
이는 클라이언트와 서버 간의 직접적인 네트워크 요청을 없애고 코드 구조 또한 단순화시킨다.
다음으로 클라이언트 컴포넌트에서 API를 직접 호출하여 서버 데이터를 호출하거나 수정했을 때와 Server Actions로 처리했을 때 코드 예시를 보며 두 방식의 차이점을 명확히 알아보겠다.
#2. 클라이언트 컴포넌트에서 API 호출 vs Server Actions
🎯 기존 클라이언트 컴포넌트에서 API를 이용해 데이터를 변경하는 경우
클라이언트 컴포넌트에서 데이터를 변경하려면 보통 API 엔드포인트(/api/endpoint)를 호출해야 한다.
이때 API 요청을 처리하기 위해
위와 같은 작업들이 필요하다.
🎯 Server Actions를 이용해 클라이언트 컴포넌트에서 데이터를 변경하는 경우
반면 Server Action을 사용하면 API 라우트를 별도로 생성할 필요 없이 서버 함수가 바로 호출된다.
즉, 클라이언트에서 직접 fetch를 작성할 필요 없이 단순히 함수를 호출하는 형태로 네트워크 요청을 수행할 수 있다.
다음으로 클라이언트 컴포넌트에서 Server Actions를 작성하는 방법에 대해 더 자세히 다루고자 한다.
#3. 클라이언트 컴포넌트에서 Server Actions 사용 방법
클라이언트 컴포넌트내에서 직접 Server action 함수 작성은 불가능하다.
다음과 같이 module로 작성된 서버 액션 함수를 import 하여 사용해야 한다.
1️⃣ Server Actions 정의하기
먼저 Server Action을 정의할 파일에 “use server” 지시어를 추가하여 서버에서 실행될 함수를 작성한다.
이 함수는 서버에서 실행되며 클라이언트에서 호출할 수 있다.
2️⃣ 클라이언트 컴포넌트에서 Server Actions 호출하기
클라이언트 컴포넌트에서 위에서 생성한 createUser와 같은 Server Action을 호출하려면 해당 Server Action이 정의된 파일을 import하여 클라이언트에서 이를 호출한다.
References
https://nextjs.org/docs/app/building-your-application/data-fetching/server-actions-and-mutations#client-components
Data Fetching: Server Actions and Mutations | Next.js
Learn how to handle form submissions and data mutations with Next.js.
nextjs.org
'Front-End > Next.js' 카테고리의 다른 글