1. Бібліотека
  2. HTTP와 웹
  3. HTTP 기본 원리

Оновлено 1 місяць тому

모든 클릭은 하나의 질문입니다. 모든 페이지 로드는 그에 대한 답입니다.

클라이언트가 묻고 서버가 응답하는 이 교환은 지구 전체에서 매초 수십억 번씩 일어납니다. 이것이 바로 요청-응답 사이클이며, HTTP가 동작하는 방식입니다. 이를 이해한다는 것은 웹 그 자체를 이해하는 것입니다.

클라이언트가 항상 먼저 말합니다

HTTP는 엄격한 규칙을 따릅니다: 클라이언트가 묻고, 서버가 대답합니다. 서버는 자발적으로 데이터를 보낼 수 없으며, 오직 여러분이 보낸 요청에만 응답할 수 있습니다.

이것은 예측 가능한 리듬을 만들어냅니다. 브라우저가 페이지를 요청합니다. 서버가 HTML을 보냅니다. 브라우저가 이미지를 요청합니다. 서버가 이미지를 보냅니다. 각 교환은 그 자체로 완결됩니다. 대화는 한 번에 하나의 질문씩 앞으로 나아갑니다.

서버는 여러분을 즉시 잊어버립니다

그런데 여기 이상한 점이 있습니다: 서버는 여러분을 기억하지 않습니다.

HTTP는 설계상 무상태(stateless)입니다. 각 요청은 마치 낯선 사람이 보낸 것처럼 도착합니다. 서버는 요청을 처리하고 응답한 다음, 그 상호작용이 있었다는 사실을 즉시 잊어버립니다. 다음 요청? 처음부터 다시 시작입니다. 이전의 일은 전혀 기억하지 못합니다.

한계처럼 보이지만, 바로 이 덕분에 웹이 이토록 거대한 규모로 작동합니다.

서버가 수백만 명의 클라이언트와 지속적인 관계를 유지하지 않아도 되기 때문에, 훨씬 더 많은 요청을 처리할 수 있습니다. 클러스터의 어떤 서버든 어떤 요청이든 처리할 수 있습니다. 서버가 충돌하고 재시작되어도? 세션이 없었으니 잃어버릴 세션도 없습니다.

그렇다면 어떻게 무언가가 여러분을 기억할 수 있을까요? 쿠키, 토큰, 세션 식별자—클라이언트가 각 요청과 함께 전달하는 데이터입니다. 서버는 이 데이터를 읽고 즉석에서 맥락을 재구성합니다. 모든 요청이 자신의 역사를 고스란히 품고 도착합니다. 마치 낯선 사람이 당신의 사진을 손에 쥔 채 나타나 당신을 안다고 주장하는 것처럼.

우리는 잊어버리도록 설계된 프로토콜 위에 웹의 기억을 쌓아올렸습니다.

요청 안을 들여다보면

모든 HTTP 요청은 네 가지 요소로 이루어집니다:

메서드는 의도를 선언합니다:

  • GET: 변경 없이 무언가를 가져옵니다
  • POST: 새로운 것을 만들기 위해 데이터를 제출합니다
  • PUT: 무언가를 완전히 교체합니다
  • PATCH: 무언가의 일부를 수정합니다
  • DELETE: 무언가를 삭제합니다

페이지를 불러올 때는 GET, 양식을 제출할 때는 POST입니다.

URL은 대상을 지정합니다:

https://api.example.com/users/123?include=profile

경로(/users/123)는 리소스를 식별합니다. 쿼리 문자열(?include=profile)은 매개변수를 전달합니다.

헤더는 맥락을 제공합니다—여러분과 여러분이 처리할 수 있는 것을 설명하는 키-값 쌍입니다:

  • Host: 요청을 보내는 도메인
  • User-Agent: 요청을 보내는 소프트웨어
  • Accept: 처리 가능한 응답 형식
  • Authorization: 인증 정보
  • Content-Type: 보내는 데이터의 형식
  • Cookie: 세션 데이터와 식별자

바디는 POST, PUT, PATCH 요청의 페이로드를 담습니다—양식 제출, JSON 데이터, 파일 업로드 등이 여기에 들어갑니다. Content-Type 헤더가 서버에게 이를 어떻게 해석해야 할지 알려줍니다.

응답 안을 들여다보면

서버의 답변은 세 부분으로 이루어집니다:

상태 코드는 결과를 세 자리 숫자로 요약합니다:

  • 2xx: 성공. 요청한 것을 받았습니다.
  • 3xx: 리다이렉트. 원하는 것이 다른 곳에 있습니다.
  • 4xx: 클라이언트 오류. 요청이 잘못되었습니다.
  • 5xx: 서버 오류. 서버에서 문제가 생겼습니다.

200 (OK)은 가장 자주 보게 됩니다. 리소스가 없을 때는 404 (Not Found), 서버 쪽에서 문제가 발생했을 때는 500 (Internal Server Error), 콘텐츠가 이동했을 때는 301 (Moved Permanently)입니다.

헤더는 응답에 대한 메타데이터를 제공합니다:

  • Content-Type: 바디의 형식
  • Content-Length: 전송되는 바이트 수
  • Set-Cookie: 향후 요청을 위해 데이터를 저장하라는 지시
  • Cache-Control: 이 응답을 얼마나 오래 재사용할 수 있는지
  • Location: 이동할 위치 (리다이렉트의 경우)

바디는 실제 내용을 담습니다—HTML, JSON, 이미지, 요청한 무엇이든.

한 번의 완전한 대화

브라우저가 API에서 사용자 데이터를 가져오는 경우:

요청:

GET /api/users/123 HTTP/1.1
Host: api.example.com
User-Agent: Mozilla/5.0
Accept: application/json
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...

응답:

HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 145
Cache-Control: max-age=300

{
  "id": 123,
  "name": "Jane Smith",
  "email": "jane@example.com",
  "created_at": "2024-01-15T10:30:00Z"
}

적절한 인증 정보로 사용자 123을 요청했고, 서버는 성공(200)을 확인하며 JSON 형식으로 데이터를 돌려줬습니다. 대화가 완결됩니다.

연결을 이어나가기

초기 HTTP는 요청마다 새로운 TCP 연결을 열었습니다. 전화 통화 중 문장과 문장 사이에 전화를 끊었다가 다시 거는 것과 같습니다.

현대 HTTP는 연결을 유지합니다. 하나의 TCP 연결로 여러 요청을 처리하여, 매번 다시 연결하는 오버헤드를 없앴습니다. HTTP/2는 한 걸음 더 나아갑니다: 단일 연결 위에서 여러 요청과 응답이 동시에 흐르며, 순서를 기다리지 않고 서로 뒤섞여 전달됩니다.

전화를 끊지 않게 되면서 대화가 빨라졌습니다.

시간은 어디로 갈까요

요청-응답 사이클은 즉각적이지 않습니다. 시간은 여러 단계에서 조금씩 쌓입니다:

  1. DNS 조회: 호스트 이름을 IP 주소로 변환
  2. TCP 핸드셰이크: 연결 수립
  3. TLS 협상: 암호화 설정 (HTTPS의 경우)
  4. 서버 처리: 응답 생성
  5. 콘텐츠 전송: 바이트 전달

캐시된 로컬 리소스는 밀리초 내에 반환됩니다. 멀리 있는 서버에 대한 복잡한 API 호출은 몇 초가 걸릴 수 있습니다. 각 단계마다 최적화 기회가 있습니다—DNS 프리페치, 연결 재사용, 응답 캐시, 콘텐츠 압축.

시간이 어디서 소모되는지 파악하는 것이 웹을 즉각적으로 느끼게 만드는 첫걸음입니다.

요청-응답 사이클에 대해 자주 묻는 질문

왜 서버는 요청 없이 먼저 데이터를 보낼 수 없나요?

HTTP는 문서 검색을 위해 설계되었습니다—페이지를 요청하면 페이지를 받습니다. 이 클라이언트 주도 방식은 모든 것을 단순하게 만듭니다: 서버는 누가 무엇을 원하는지 추적하지 않아도 되고, 방화벽이 원치 않는 수신 트래픽을 따로 막아낼 필요도 없으며, 아키텍처는 자연스럽게 확장됩니다. 진정한 서버 주도 통신이 필요할 때는 WebSockets 같은 기술이 양방향으로 데이터가 흐를 수 있는 지속적인 연결을 수립합니다.

요청이 응답을 받지 못하면 어떻게 되나요?

클라이언트는 타임아웃을 구현합니다. 설정된 시간 내에 (보통 30~60초) 응답이 없으면 연결이 중단되고 오류가 발생합니다. 서버가 이미 요청을 받고 처리했을 수도 있습니다—알 방법이 없습니다. 이 불확실성 때문에 신뢰할 수 없는 네트워크에서는 멱등적(idempotent) 연산, 즉 몇 번을 반복해도 결과가 같은 연산이 중요합니다.

HTTP가 무상태라면 쿠키는 어떻게 상태를 유지하나요?

서버는 응답에 Set-Cookie 헤더를 포함합니다. 브라우저는 이 쿠키를 저장하고 해당 도메인에 대한 모든 후속 요청에 자동으로 첨부합니다. 서버는 쿠키를 읽고 세션을 재구성합니다. HTTP 자체는 여전히 무상태입니다—상태가 서버에 머무는 것이 아니라 각 요청과 함께 이동하는 것입니다. 프로토콜은 잊어버리지만, 쿠키는 기억합니다.

Ця сторінка була корисною?

😔
🤨
😃
요청-응답 사이클 • Бібліотека • Connected