Next.js App Router를 쓰기 시작하면 가장 많이 나오는 질문 중 하나가 “이건 Server Action으로 만들까, API Route로 만들까?”입니다. 처음에는 Server Action이 코드도 짧고 편해 보여서 모든 요청을 그쪽으로 몰아 넣기 쉽습니다. 하지만 운영 단계로 들어가면 선택의 기준이 달라집니다.
실무에서 실제로 겪는 상황은 대체로 다음과 같습니다.
- 간단한 폼 제출은 Server Action이 편한데, 권한 검증은 어디서 해야 할지 애매하다
- 여러 단계의 DB 작업이 필요한데, 트랜잭션 범위를 어떻게 잡아야 할지 고민된다
- 에러가 발생했을 때, 화면 제어와 로그를 어떻게 분리해야 할지 헷갈린다
이번 글에서는 “어떤 게 더 좋다”가 아니라, 어떤 상황에서 무엇을 선택해야 운영이 안정적인지를 기준으로 정리합니다.
- Server Actions와 API Route의 역할 차이
- 권한 검증과 책임 분리 관점에서의 선택 기준
- 트랜잭션·에러 처리·로깅을 고려한 설계 포인트
- 실무에서 자주 발생하는 선택 실패 사례
개념/배경 설명
Server Actions는 서버에서 실행되는 함수로, 클라이언트 컴포넌트에서 직접 호출할 수 있습니다. API Route는 HTTP 엔드포인트로, 클라이언트가 네트워크 요청을 통해 접근합니다.
기능적으로는 둘 다 “서버에서 로직을 실행한다”는 점에서 비슷해 보이지만, 운영 관점에서는 성격이 꽤 다릅니다.
- Server Action: UI 흐름에 밀접, 컴포넌트 중심
- API Route: 시스템 경계, 외부/내부 계약 중심
이 차이를 무시하고 아무 데나 쓰기 시작하면, 권한 로직이 UI에 섞이거나, 에러 처리가 화면마다 달라지는 문제가 생깁니다.
핵심 설계 1: 책임 경계로 선택한다
가장 중요한 기준은 “이 로직의 책임이 어디에 있는가”입니다.
- UI 이벤트에 강하게 결합된 처리 → Server Action
- 비즈니스 규칙, 외부 연동, 재사용 로직 → API Route
예를 들어 “프로필 닉네임 수정” 같은 기능은 특정 화면의 폼 제출과 1:1로 연결되어 있습니다. 이 경우 Server Action이 자연스럽습니다.
반대로 “모든 기기 로그아웃”, “결제 취소”, “권한 변경”처럼 다른 화면이나 시스템에서도 호출될 수 있는 기능은 API Route로 분리하는 편이 운영에 유리합니다.
실무 포인트 정리
- Server Action은 UI의 일부다
- API Route는 시스템의 일부다
- 재사용 가능성이 보이면 API Route 쪽으로 기운다
핵심 설계 2: 권한 검증은 어디에 둘 것인가
권한 검증은 Server Action과 API Route 선택을 가르는 핵심 요소입니다.
Server Action에서도 인증 정보는 얻을 수 있지만, 권한 규칙이 복잡해질수록 문제가 생깁니다.
- 여러 Action에서 같은 권한 체크 코드가 반복된다
- UI 변경과 함께 권한 로직이 수정된다
- 어느 화면에서 어떤 권한이 필요한지 파악하기 어렵다
API Route를 사용하면, 요청의 시작 지점에서 권한을 일관되게 검증할 수 있습니다. 또한 로그와 모니터링 포인트를 한 곳에 모으기 쉽습니다.
// API Route 예시
export async function POST(req: Request) {
const user = await requireAuth(req);
requireRole(user, 'ADMIN');
// 이후 비즈니스 로직
}
실무 포인트 정리
- 권한 규칙이 단순하면 Server Action도 가능하다
- 역할/등급/정책이 붙기 시작하면 API Route가 안정적이다
- 권한은 “여기저기”가 아니라 “한 곳”에서 관리한다
핵심 설계 3: 트랜잭션과 에러 처리 관점
DB 트랜잭션이나 외부 API 연동이 포함되면, 에러 처리 전략이 중요해집니다.
Server Action에서는 에러가 UI 흐름과 바로 연결됩니다. 이 점은 단순한 경우에는 장점이지만, 다음 상황에서는 오히려 부담이 됩니다.
- 여러 단계의 트랜잭션이 필요한 경우
- 부분 성공/부분 실패를 구분해야 하는 경우
- 에러를 사용자 메시지와 운영 로그로 분리해야 하는 경우
API Route에서는 에러를 HTTP 응답으로 명확히 표현하고, Server Action이나 UI에서는 “결과 처리”만 담당하게 만들 수 있습니다.
// API Route 결과
return NextResponse.json(
{ ok: false, error: { code: 'INSUFFICIENT_BALANCE' } },
{ status: 400 },
);
실무 포인트 정리
- 에러 종류가 많아질수록 API Route가 유리하다
- Server Action은 성공/실패가 단순할 때 빛난다
- 운영 로그와 사용자 메시지는 분리해야 한다
선택 기준 요약: A vs B
- UI 전용, 단순 처리 → Server Action
- 권한·정책·재사용 로직 → API Route
- 복잡한 트랜잭션 → API Route
- 폼 제출, 설정 저장 → Server Action
운영/실무에서 자주 겪는 문제
- 모든 로직을 Server Action으로 만들어 테스트/재사용이 어려워진 경우
- API Route가 없어서 외부 연동 시 구조를 다시 만드는 경우
- 에러 처리가 UI마다 달라 CS 대응이 어려워진 경우
- 권한 체크 누락으로 특정 화면에서만 보안 이슈가 발생한 경우
실무 권장 체크리스트
- 이 로직이 UI에 종속적인지, 시스템에 종속적인지 구분했는가
- 권한 검증 위치가 일관적인가
- 트랜잭션과 에러 처리를 한 곳에서 통제할 수 있는가
- 향후 다른 클라이언트(모바일, 어드민)에서 재사용할 가능성은 없는가
Server Actions와 API Route의 선택은 “최신 기능을 쓰느냐”의 문제가 아닙니다.
UI 흐름을 단순하게 만들고 싶다면 Server Action, 운영과 확장을 생각한다면 API Route를 선택하는 것이 자연스럽습니다. 두 도구를 섞어 쓰되, 기준 없이 섞지 않는 것이 실무에서 가장 중요합니다.
'개발 > Typescript' 카테고리의 다른 글
| [TYPESCRIPT] Nextjs 권한 테스트 전략: Authorization 로직을 테스트로 고정 방법 (0) | 2026.01.19 |
|---|---|
| [TYPESCRIPT] Nextjs 권한(Authorization) 설계 전략: 역할·정책·리소스 모델링 (0) | 2026.01.18 |
| [TYPESCRIPT] Next.js 데이터 접근 계층 설계: fetch 래퍼·에러 표준화·캐시 전략 (0) | 2026.01.16 |
| [TYPESCRIPT] Next.js + TypeScript 프로젝트 구성 전략: 운영과 유지보수를 고려한 폴더·설정·규칙 (0) | 2026.01.15 |
| [TYPESCRIPT] 실무 기준 인증 구조 점검 체크리스트: 초기 서비스부터 성장 단계까지 설계 기준 정리 (0) | 2026.01.14 |
