이 문서를 통해 아래 질문들에 답할 수 있게 됩니다.

  • 조회, 결제, 업로드, 다운로드, WebSocket 요청은 왜 같은 timeout/retry/cache 정책을 쓰면 안 되는가?
  • 요청 유형별로 백엔드와 인프라가 각각 확인해야 할 설정은 무엇인가?
  • 개인 프로젝트에서도 요청 유형별 운영 품질을 높이려면 어떤 최소 기준을 둘 수 있는가?

개요

네트워크 판단은 요청 유형에 따라 달라진다. 조회 API는 cache와 p95 latency가 중요하고, 결제 API는 idempotency와 중복 실행 방지가 중요하다. 파일 업로드는 body size와 streaming, WebSocket은 idle timeout과 heartbeat, 모바일 요청은 네트워크 전환과 retry를 봐야 한다.

따라서 “API가 느리다”, “502가 난다”, “timeout이 난다” 같은 증상도 요청 유형을 먼저 분류하면 의심 계층과 해결책이 훨씬 빨리 좁혀진다.

왜 백엔드 개발자가 알아야 하는가

백엔드 개발자는 endpoint를 구현할 때 사실상 네트워크 계약도 함께 설계한다.

  • 결제 POST에 retry를 허용하려면 idempotency key와 상태 조회가 필요하다.
  • 업로드 endpoint는 app 코드보다 proxy body limit에서 먼저 막힐 수 있다.
  • 다운로드 endpoint는 app 서버가 직접 파일을 들고 있으면 bandwidth 병목이 된다.
  • WebSocket/SSE는 일반 REST timeout으로 운영하면 주기적으로 끊긴다.
  • 관리자 batch 요청은 일반 사용자 traffic과 같은 pool을 쓰면 운영 장애를 만들 수 있다.

요청 유형을 모르면 모든 endpoint에 같은 timeout, retry, cache, 보안 정책을 복사하게 된다.

요청 흐름에서의 위치

요청 유형은 HTTP method보다 넓은 개념이다.

사용자 의도
→ 요청 유형 분류
→ HTTP method / path / header / body
→ proxy / LB / app 정책
→ dependency 정책
→ 응답과 재시도 정책

같은 POST라도 검색 조건 제출, 주문 생성, 파일 업로드, 결제 승인은 완전히 다른 네트워크 판단을 가진다.

원리

요청 유형별로 민감한 축이 다르다.

요청 유형민감한 요소백엔드 기준인프라 기준
일반 조회 APIlatency, cache, paginationETag, 조건부 요청, query 최적화CDN cache, origin timeout
생성/수정/삭제idempotency, validation, lock중복 요청 방지, transaction 경계retry 정책, WAF body 검사
결제/주문/예약중복 side effect, 외부 APIidempotency key, 상태 저장, reconciliationdependency timeout, retry budget
로그인/인증cookie, redirect, CORSSameSite, Secure, CSRF, sessionTLS termination, domain, header 전달
파일 업로드body size, slow client, 임시 저장multipart limit, streaming, virus scanbody limit, proxy timeout, object storage
파일 다운로드bandwidth, range, CDNrange 지원, signed URL, streamingCDN, object storage, egress
외부 API 연동timeout, pool, breakerdependency별 client, fallbackegress, NAT, firewall, DNS
긴 처리 요청client timeout, 작업 상태202 Accepted, job id, pollingproxy/LB timeout, queue
모바일 앱 요청네트워크 전환, retryidempotent API, 버전 호환regional latency, CDN
브라우저 요청CORS, cookie, cacheorigin 허용, credential, preflightWAF, CDN header, TLS
관리자/배치대량 처리, 권한, ratepagination, job 분리, audit내부망, IP allowlist
WebSocket/SSE장기 연결, heartbeatreconnect, heartbeat, backpressureupgrade, idle timeout, connection limit

이 표의 목적은 endpoint별 runbook과 설정 리뷰의 출발점을 만드는 것이다.

요청 유형별 장애 예시

  • 조회 API 500ms 증가
    • cache miss 증가, DB query plan 변경, pagination 누락, CDN bypass를 본다.
  • 주문 POST timeout
    • idempotency key, transaction state, 외부 결제 호출, retry 중복을 본다.
  • 업로드 413
    • NGINX client_max_body_size, API Gateway payload limit, multipart 설정을 본다.
  • 다운로드 중간 끊김
    • range request, CDN, object storage, client bandwidth, proxy buffering을 본다.
  • WebSocket 60초마다 끊김
    • LB/proxy idle timeout과 heartbeat interval을 본다.
  • 모바일에서만 중복 주문
    • 네트워크 전환 retry, client timeout, idempotency key 재사용을 본다.

실무에서 자주 만나는 문제

  • 조회 API와 결제 API에 같은 retry 정책을 적용한다.
    • 조회는 retry가 비교적 안전하지만 결제는 중복 side effect가 치명적이다.
    • 요청 유형별 retry 가능 조건을 문서화한다.
  • 파일 업로드 장애를 app validation으로만 본다.
    • body limit은 CDN/proxy/LB/app 여러 계층에 있다.
    • 각 계층의 최대 body size와 timeout을 표로 맞춘다.
  • 긴 작업을 동기 HTTP로 유지한다.
    • proxy timeout과 client timeout에 취약하다.
    • job id를 반환하고 polling 또는 callback으로 전환한다.
  • WebSocket을 일반 REST route와 같은 설정에 둔다.
    • upgrade header, idle timeout, heartbeat, connection limit이 다르다.
    • 별도 route와 모니터링을 둔다.

디버깅 방법

장애 보고를 받으면 먼저 요청 유형을 표시한다.

요청 유형:
사용자 영향:
side effect 여부:
retry 가능 여부:
idempotency key 필요 여부:
cache 가능 여부:
body size:
expected duration:
browser/mobile/server-to-server:
long-lived connection 여부:

그 다음 유형별로 보는 증거가 달라진다.

# 업로드 body limit 확인
curl -v -X POST https://example.com/upload \
  -H 'Content-Type: application/octet-stream' \
  --data-binary @large-file.bin
 
# 브라우저 요청의 CORS/preflight 확인
curl -i -X OPTIONS https://api.example.com/orders \
  -H 'Origin: https://www.example.com' \
  -H 'Access-Control-Request-Method: POST'
 
# WebSocket handshake header 확인
curl -i -N \
  -H 'Connection: Upgrade' \
  -H 'Upgrade: websocket' \
  https://example.com/ws

명령은 완전한 재현이 아니라 어느 계층까지 조건을 만족하는지 확인하는 도구다.

코드로 확인하기

결제/주문류 요청은 idempotency key를 API 계약으로 드러낸다.

POST /orders HTTP/1.1
Content-Type: application/json
Idempotency-Key: order-20260630-001

긴 작업은 동기 처리 대신 작업 리소스를 반환한다.

HTTP/1.1 202 Accepted
Location: /jobs/abc123
Retry-After: 3

이 방식은 proxy timeout에 덜 취약하고 사용자가 상태를 다시 조회할 수 있다.

주니어가 자주 하는 오해

  • HTTP method만 같으면 같은 정책을 적용해도 된다고 생각한다.
    • 같은 POST라도 검색, 결제, 업로드는 retry와 timeout 기준이 다르다.
  • upload/download를 일반 JSON API와 같이 본다.
    • body size, streaming, bandwidth, object storage, proxy buffering이 중요하다.
  • WebSocket은 연결만 되면 끝이라고 생각한다.
    • idle timeout, heartbeat, reconnect, connection 수가 운영 핵심이다.
  • 모바일 요청은 브라우저 요청과 같다고 본다.
    • 네트워크 전환, offline retry, 앱 버전 호환이 추가된다.

시니어의 설계 판단 기준

  • endpoint 설계 리뷰에 요청 유형, side effect, retry 가능성, timeout, cache, body size를 포함한다.
  • critical side effect 요청에는 idempotency와 상태 조회 API를 요구한다.
  • optional dependency가 포함된 요청은 fallback 또는 partial response를 검토한다.
  • 긴 작업은 HTTP connection을 붙잡을지, queue/job으로 분리할지 결정한다.
  • 인프라 route는 REST, upload, streaming, admin, internal traffic을 필요하면 분리한다.

인프라 협업 포인트

  • 업로드 route는 body limit, buffering, timeout, temporary storage 위치를 맞춘다.
  • 다운로드는 CDN/object storage offload와 signed URL을 검토한다.
  • WebSocket/SSE는 upgrade, idle timeout, max connection, pod eviction 영향을 함께 본다.
  • 관리자/배치 요청은 rate limit, IP allowlist, 내부망 routing, audit log를 맞춘다.
  • 모바일 트래픽은 region, CDN, retry storm, version rollout을 인프라 지표와 연결한다.

실전 팁

  • API 문서에 “retry 가능 여부”와 “idempotency 필요 여부”를 표시한다.
  • 개인 프로젝트라도 업로드 최대 크기와 timeout을 명시하면 운영 완성도가 올라간다.
  • 결제/주문 API는 timeout 테스트보다 중복 요청 테스트가 더 중요할 때가 많다.
  • WebSocket/SSE는 연결 수가 늘 때 memory와 file descriptor를 꼭 본다.

위험 신호!

  • 모든 endpoint가 같은 timeout, retry, cache 정책을 쓴다.
  • POST 요청에 side effect 여부와 idempotency 정책이 문서화되어 있지 않다.
  • 업로드 제한이 CDN/proxy/app에서 서로 다르다.
  • 긴 작업이 proxy timeout보다 오래 걸리는데 동기 HTTP로만 제공된다.
  • WebSocket route에 heartbeat와 idle timeout 테스트가 없다.

확인 질문

확인 질문

  • 결제 요청과 조회 요청의 retry 정책이 달라야 하는 이유는 무엇인가?
    • 결제는 중복 side effect가 치명적이므로 idempotency와 상태 저장 없이 retry하면 안 되고, 조회는 상대적으로 retry 위험이 낮기 때문이다.
  • 업로드 413이 발생하면 어디를 확인해야 하는가?
    • CDN, API Gateway, NGINX, application multipart limit 등 body size 제한이 있는 모든 계층을 확인해야 한다.
  • 긴 처리 요청을 202 Accepted와 polling으로 바꾸는 이유는 무엇인가?
    • HTTP connection과 proxy timeout에 오래 묶이지 않고 작업 상태를 별도 리소스로 관리하기 위해서다.

참고 문서