fetch, Route Handler, Server Action은 모두 네트워크 요청을 처리할 때 사용할 수 있지만, 각각의 목적과 사용 환경에 차이가 있습니다.
fetch는 클라이언트와 서버 모두에서 사용할 수 있는 기본적인 네트워크 요청 함수입니다. 브라우저 환경과 Node.js 서버 환경에서 모두 작동하기 때문에 어느 환경에서나 네트워크 요청을 보낼 수 있는 범용적인 도구입니다.
import React, { useEffect, useState } from "react";
function FetchExample() {
const [data, setData] = useState(null);
useEffect(() => {
fetch("/api/data") // API 엔드포인트 호출
.then((response) => response.json())
.then((data) => setData(data))
.catch((error) => console.error("Error:", error));
}, []);
return <div>{data ? <p>데이터: {JSON.stringify(data)}</p> : <p>로딩 중...</p>}</div>;
}
export default FetchExample;
Server Action은 Next.js에서 서버 환경에서만 동작하는 기능입니다. 리액트 컴포넌트 내부에서 서버 쪽에서 실행되는 로직을 구현할 때 사용합니다. 이를 통해 클라이언트가 아닌 서버에서 데이터를 처리하는 코드를 작성할 수 있습니다. 주로 서버에서만 실행되는 동작이 필요할 때 사용되며, 클라이언트에서는 이를 직접 호출할 수 없습니다.
// app/api/serverApi.ts
export async function sendContactForm(formData: FormData) {
const res = await fetch("/api/contact", {
method: "POST",
body: formData,
});
if (!res.ok) {
throw new Error("서버와 통신 중 오류가 발생했습니다.");
}
return await res.json();
}
// app/contact/page.tsx
"use client";
import React, { useState } from "react";
import { sendContactForm } from "../api/serverApi"; // serverApi에서 import
export default function ContactPage() {
const [name, setName] = useState<string>("");
const [message, setMessage] = useState<string>("");
const [responseMessage, setResponseMessage] = useState<string | null>(null);
async function handleSubmit(e: React.FormEvent) {
e.preventDefault();
const formData = new FormData();
formData.append("name", name);
formData.append("message", message);
try {
const response = await sendContactForm(formData);
setResponseMessage(response.message);
} catch (error) {
setResponseMessage("전송 중 오류가 발생했습니다.");
}
}
return (
<div>
<h1>문의하기</h1>
<form onSubmit={handleSubmit}>
<label>
이름:
<input type="text" value={name} onChange={(e) => setName(e.target.value)} required />
</label>
<br />
<label>
메시지:
<textarea value={message} onChange={(e) => setMessage(e.target.value)} required />
</label>
<br />
<button type="submit">전송</button>
</form>
{responseMessage && <p>{responseMessage}</p>}
</div>
);
}
Route Handler는 Next.js에서 API 엔드포인트를 정의할 때 사용하는 도구입니다. 이것은 컴포넌트 외부에서 동작하며, 클라이언트와 서버 간의 네트워크 요청을 처리하는 전용 함수입니다. 클라이언트가 서버에 요청을 보낼 수 있도록 경로(route)를 생성해 주며, 요청을 받고 처리하는 로직을 작성할 수 있습니다.
// app/api/welcome/route.ts
import { NextResponse } from "next/server";
export async function POST(request: Request) {
const { name } = await request.json(); // 요청에서 JSON 데이터를 추출
const message = `안녕하세요, ${name}님! 환영합니다.`; // 환영 메시지 생성
return NextResponse.json({ message }); // 클라이언트에 응답
}
// 클라이언트에서 API 호출
async function sendWelcomeRequest(name: string) {
// /api/welcome 엔드포인트에 POST 요청
const response = await fetch("/api/welcome", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ name }),
});
const data = await response.json();
console.log(data.message); // "안녕하세요, [이름]님! 환영합니다."
}
// 사용 예시
sendWelcomeRequest("철수");
fetch : 클라이언트나 서버에서 데이터를 가져오는 기본적인 네트워크 요청을 보낼 때 사용.Server Action : 서버에서만 실행되어야 할 리액트 컴포넌트 내부 로직을 구현할 때 사용. 서버 전용.Route Handler : 클라이언트가 서버에 요청을 보낼 수 있는 API 경로를 정의할 때 사용. 엔드포인트 생성. 클라이언트와 서버가 모두 연관된 네트워크 요청을 처리하는 경우 사용.아래 두 문장의 차이를 좀 더 구체적으로 알아보자.