티스토리 뷰
✅ route.ts(라우트 API) vs. Server Actions 비교
라우트 API (route.ts) 서버 액션 (use server)
방식 | HTTP 요청(예: fetch, axios)을 통해 API 엔드포인트를 호출 | 서버에서 직접 함수를 호출하여 실행 |
사용법 | app/api/.../route.ts에 작성 (GET, POST, PUT, DELETE 가능) | use server 키워드를 사용하여 서버 함수 실행 |
보안 | API 호출을 통한 요청이므로 CSRF 방어 필요 | 클라이언트에서 직접 실행할 수 없어 CSRF 공격 걱정 없음 |
유연성 | 외부 API와의 통합이 용이 | 클라이언트와의 직접적인 상호작용에 적합 |
상태 관리 | fetch 요청으로 데이터를 가져와야 함 | 클라이언트 컴포넌트에서 바로 실행 가능 |
최적화 | 캐싱 및 CDN을 활용할 수 있음 | 페이지 새로고침 없이 상태 변경 가능 |
🔥 route.ts(API Routes)를 사용하는 이유
1️⃣ 다른 클라이언트(모바일 앱, 외부 서비스)와 공유 가능
라우트 API는 Next.js 프론트엔드뿐만 아니라, 모바일 앱(React Native, iOS, Android)이나 다른 웹사이트에서도 API로 사용할 수 있음.
반면, 서버 액션은 Next.js 내부에서만 사용 가능.
예: route.ts를 사용하면 https://yourdomain.com/api/register와 같은 API 엔드포인트를 만들어, 모바일 앱에서도 회원가입 요청 가능.
2️⃣ RESTful API 구조를 활용 가능
✅ route.ts는 **HTTP 메서드(GET, POST, PUT, DELETE)**를 활용할 수 있어 RESTful API 패턴을 따를 수 있음.
✅ 서버 액션은 주로 POST 요청에 적합하며, RESTful API처럼 다양한 메서드를 활용하기 어려움.
예:
- GET /api/members → 회원 목록 조회
- POST /api/members → 회원가입
- PUT /api/members/:id → 회원 정보 수정
- DELETE /api/members/:id → 회원 삭제
이렇게 명확한 API 설계를 유지할 수 있음.
3️⃣ 캐싱 및 성능 최적화 가능
route.ts는 API 응답을 캐싱하거나 CDN을 활용하여 클라이언트에서 빠르게 로드할 수 있음.
서버 액션은 이런 최적화가 어려운 경우가 많음.
✅ 예: GET /api/products 요청을 캐싱하면 동일한 데이터를 빠르게 제공 가능.
4️⃣ Middleware 및 인증(Token-based, JWT 등) 적용 용이
라우트 API에서는 JWT, OAuth, 세션 인증 등의 보안 적용이 용이함.
반면, 서버 액션은 클라이언트에서 바로 실행되기 때문에 토큰을 활용한 인증이 어렵거나 제한적임.
✅ 예:
- route.ts에서 Authorization: Bearer {token}을 검사하여 인증된 사용자만 요청 가능.
- 서버 액션은 Next.js 내부에서만 동작하므로 이런 인증 방식과는 조금 다름.
5️⃣ CSRF 보안 문제 해결 가능
✅ API Routes(route.ts)는 외부에서 호출 가능하기 때문에 CSRF 방어 필요.
✅ 서버 액션은 Next.js 내부에서만 실행되므로 CSRF 위험이 없음.
하지만, API Routes는 CSRF 방어를 위해 CSRF 토큰, SameSite 쿠키 정책 등을 적용 가능.
🚀 결론: 언제 route.ts를 사용하고, 언제 서버 액션을 사용할까?
✔ 라우트 API(route.ts)가 적합한 경우
- 외부 서비스(모바일 앱, 다른 웹사이트)와 API를 공유해야 할 때
- JWT, OAuth 같은 인증 시스템을 적용해야 할 때
- RESTful API 설계를 유지하고 싶을 때
- HTTP 캐싱, CDN을 활용하여 성능을 최적화하고 싶을 때
✔ 서버 액션이 적합한 경우
- Next.js 내부에서만 데이터를 처리하면 될 때
- 클라이언트에서 서버 요청을 간단하게 처리하고 싶을 때
- CSRF 공격이 걱정되지 않는 경우
- 상태를 즉시 업데이트해야 할 때
👉 회원가입(register), 로그인(login), 사용자 프로필(profile) 조회 등의 API는 route.ts를 활용하는 것이 더 좋음.
👉 간단한 데이터 업데이트(Form 제출)라면 서버 액션(use server)을 활용하는 것이 편리함.
✅ 추천하는 구조 (회원가입 예제)
회원가입을 Next.js에서 구현할 때 이런 구조를 추천합니다.
1️⃣ route.ts를 사용한 API (회원가입)
📌 /app/api/register/route.ts
"use server";
import { NextResponse } from "next/server";
import mysql from "mysql2/promise";
import { hash } from "bcryptjs";
export async function POST(request: Request) {
const { email, password, name } = await request.json();
if (!email || !password) return NextResponse.json({ error: "필수값 누락" }, { status: 400 });
const hashedPassword = await hash(password, 10);
const connection = await mysql.createConnection({
host: process.env.MYSQL_HOST!,
user: process.env.MYSQL_USER!,
password: process.env.MYSQL_PASSWORD!,
database: process.env.MYSQL_DATABASE!,
});
await connection.execute("INSERT INTO members (email, password, name) VALUES (?, ?, ?)", [email, hashedPassword, name]);
await connection.end();
return NextResponse.json({ message: "회원가입 성공!" }, { status: 200 });
}
2️⃣ 클라이언트에서 API 호출
📌 /app/register/page.tsx
"use client";
import { useState } from "react";
export default function RegisterPage() {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
const res = await fetch("/api/register", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ email, password }),
});
const data = await res.json();
alert(data.message);
};
return (
<form onSubmit={handleSubmit}>
<input type="email" value={email} onChange={(e) => setEmail(e.target.value)} placeholder="이메일 입력" />
<input type="password" value={password} onChange={(e) => setPassword(e.target.value)} placeholder="비밀번호 입력" />
<button type="submit">회원가입</button>
</form>
);
}
🔥 결론: 실무에서는 route.ts와 server actions을 함께 활용!
- 회원가입, 로그인 등은 route.ts로 API 엔드포인트를 만들어 사용
- Form 전송과 같은 간단한 데이터 처리는 server actions을 활용
- Total
- Today
- Yesterday
- 스프링 시큐리티(spring security)-http basic 인증
- docker
- await
- 표현 언어(expression language)
- .submit()
- jsp 오픈 소스
- 문자 자르기
- 인텔리제이(intellij)
- system.io
- jstl(java standard tag library)-core
- 스프링 프레임워크(spring framewordk)
- error-java
- In App Purchase
- 스프링 시큐리티(spring security)
- MainActor
- 스프링 프레임워크(spring framework)
- 람다식(lambda expression)
- 제품 등록
- 진수 변환
- java 키워드 정리
- java.sql
- REST API
- java-개발 환경 설정하기
- nl2br
- jstl(java standard tag library)
- 메이븐(maven)
- React
- 특정 문자를 기준으로 자르기
- System.Diagnostics
- java web-mvc
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |