"HTTP 헤더는 수백 개지만 전부 외울 필요는 없어. 역할별로 묶어 보면 낯선 헤더도 어디에 쓰이는지 빠르게 짐작할 수 있어."
실무의 대부분을 설명하는 다섯 범주
IANA 레지스트리에는 수많은 HTTP 필드가 등록되어 있고, 애플리케이션이 정의한 필드도 많아. 이름을 하나씩 외우기보다 역할을 기준으로 분류해 보자. 일부 헤더는 둘 이상의 역할을 맡지만, 다음 다섯 범주를 기준으로 보면 실제 요청과 응답을 훨씬 수월하게 읽을 수 있어.
- 요청 제어와 협상 — 클라이언트가 요청 처리 조건과 원하는 응답 형식을 서버에 전달해.
Host,Authorization,Accept,Accept-Encoding,Accept-Language,User-Agent,Cookie,Origin,Referer가 여기에 들어가. - 응답 제어 — 서버가 응답 처리 방법이나 이후 요청에 필요한 정보를 알려 줘.
Server,Set-Cookie,WWW-Authenticate,Location,Vary,Allow,Retry-After가 대표적이야. - 표현 메타데이터 — 요청이나 응답의 본문 표현을 설명해.
Content-Type,Content-Length,Content-Encoding,Content-Language,Last-Modified,ETag를 자주 만나. - 캐시와 조건부 요청 — 저장된 응답을 언제 재사용하고 다시 검증할지 조율해.
Cache-Control,Expires,ETag,If-None-Match,If-Modified-Since,Vary가 이 역할을 맡아. ETag와 Vary처럼 다른 범주와 겹치는 필드도 있어. 트랙 5에서 자세히 다룰 거야. - 연결과 전송 — HTTP/1.1 연결과 메시지 전송 방식을 제어해.
Connection,Keep-Alive,Transfer-Encoding,Upgrade가 대표적이야. HTTP/2와 HTTP/3에서는 연결별 헤더 상당수가 금지되거나 이진 프레임 기능으로 대체돼.
실제 교환을 범주로 읽기
원시 요청이나 응답을 만나면 헤더를 하나씩 이 범주에 놓아 봐. 어떤 필드가 본문을 설명하고, 어떤 필드가 캐시 정책을 전하며, 어떤 필드가 인증과 세션을 이어 주는지 구분하면 문서를 열기 전에도 메시지의 의도를 상당 부분 파악할 수 있어.
헤더는 본문을 건드리지 않고 통신 조건을 조율하는 공간이야. Content-Type, 언어, 인코딩, 최신성, 인증, 세션 정보를 헤더에 담으면 본문은 업무 데이터 자체에 집중할 수 있어. 물론 업무 데이터로서 requested_language가 필요할 수는 있지만, HTTP의 콘텐츠 협상을 다시 발명하려고 같은 필드를 넣는다면 기존 헤더를 먼저 검토해야 해.
사용자 정의 헤더 — 새 필드에 X- 접두사를 붙이지 마
오랫동안 사용자 정의 헤더에는 X- 접두사를 붙이는 관례가 있었어(X-Request-ID, X-Forwarded-For). RFC 6648(2012)은 이 관례를 공식적으로 폐기하도록 권고했어. 새 필드는 Pippa-Request-ID, Stripe-Signature, cf-ray처럼 용도와 소유자가 드러나는 이름을 고르면 돼. 다만 기존 X- 헤더를 무턱대고 바꾸라는 뜻은 아니야. X-Forwarded-For처럼 널리 배포된 필드는 호환성을 위해 그대로 유지하고, 새 API에서 X- 접두사 관례를 되풀이하지 않는 것이 핵심이야.
cwkPippa에서 볼 수 있는 헤더
전형적인 cwkPippa 요청에는
Host: localhost:8000, Authorization: Bearer ..., Accept: application/json, Content-Type: application/json(POST 본문이 있을 때), User-Agent가 들어가. 응답에서는 Content-Type: application/json과 Content-Length 같은 표현 메타데이터를 보고, HTTP/1.1 연결에는 Connection: keep-alive가 나타날 수 있어. 정적 자산에는 Cache-Control이 붙기도 하지. HTTP/1.1 SSE 응답의 Content-Type: text/event-stream은 브라우저가 이벤트 스트림으로 해석해야 한다는 뜻이고, Transfer-Encoding: chunked는 본문을 길이가 정해진 한 덩어리가 아니라 청크로 전송한다는 뜻이야.