← 전체 글로 돌아가기

Next.js

Next.js route handler는 항상 상태 코드를 명확히 해야 한다

HTTP 상태 코드를 제대로 주지 않으면 클라이언트에서 성공/실패를 판단할 수 없고, 캐싱 정책도 깨진다.

Next.js로 API 라우트를 만들 때 자주 하는 실수가 있다. 요청이 성공했는데 200이 아닌 상태 코드를 주거나, 반대로 실패했는데 200을 주는 것이다.

HTTP 상태 코드의 역할

HTTP 상태 코드는 단순한 숫자가 아니다. 클라이언트가 응답을 어떻게 처리해야 할지를 알려주는 신호다.

  • 200: 성공. 클라이언트는 응답을 신뢰하고 캐시할 수 있다
  • 400: 클라이언트 오류. 요청 데이터를 다시 확인해야 한다
  • 401: 인증 필요. 로그인 페이지로 리다이렉트해야 한다
  • 404: 리소스 없음. 이 엔드포인트는 더 이상 존재하지 않는다
  • 500: 서버 오류. 나중에 다시 시도할 수 있다

Next.js route handler에서 명확한 상태 코드 주기

// ❌ 안 좋은 예: 항상 200을 주고 body에만 상태 정보를 넣음
export async function POST(req) {
  try {
    // ...
    return Response.json({ success: true, data });
  } catch (error) {
    return Response.json({ success: false, error: error.message });
    // 이것도 200 상태 코드다!
  }
}

// ✅ 좋은 예: 상황에 맞는 상태 코드를 명시
export async function POST(req) {
  const body = await req.json();

  if (!body.email) {
    return Response.json(
      { error: "Email is required" },
      { status: 400 }
    );
  }

  try {
    const result = await db.create(body);
    return Response.json(
      { success: true, data: result },
      { status: 201 }
    );
  } catch (error) {
    return Response.json(
      { error: error.message },
      { status: 500 }
    );
  }
}

검증과 테스트

실제 배포된 엔드포인트에서 상태 코드가 제대로 나오는지 확인하는 게 중요하다.

# 성공 케이스
curl -i -X POST https://example.com/api/items \
  -H "Content-Type: application/json" \
  -d '{"name":"test"}'
# 응답에 201 상태 코드가 있는가?

# 실패 케이스
curl -i -X POST https://example.com/api/items \
  -H "Content-Type: application/json" \
  -d '{}'
# 응답에 400 상태 코드가 있는가?

캐싱과 CDN

CDN이나 캐시 레이어는 상태 코드를 보고 캐싱 여부를 결정한다. 2xx는 캐시하고, 4xx나 5xx는 캐시하지 않는다. 상태 코드를 잘못 주면 캐싱이 꼬이고, 성능도 떨어진다.

API를 만들 때는 '응답이 나왔으니 됐다'가 아니라 '정확한 상태 코드를 줬는가'를 먼저 확인해야 한다.