티스토리 뷰

안녕하세요, WoodyCode입니다. 🚀

 

우리는 보통 axios나 fetch 라이브러리를 사용해 데이터를 가져오면 "통신을 이해했다"고 착각하곤 합니다. 하지만 프레임워크의 유행이 변해도 변하지 않는 웹의 진짜 밑바닥, 바로 HTTP를 제대로 이해하지 못하면 서비스가 커졌을 때 발생하는 성능 병목과 보안 이슈 앞에서 무력해지기 쉽습니다.

오늘은 브라우저와 서버가 대화하는 언어, HTTP의 핵심 아키텍처를 실무적인 관점에서 해부해 보겠습니다.


1. 요청(Request)과 응답(Response)

HTTP는 기본적으로 클라이언트(브라우저)가 요청을 보내고, 서버가 응답을 하는 구조입니다. 이 단순한 구조 안에 웹의 모든 것이 담겨 있습니다.

구성 요소 핵심 내용
메서드(Method) GET, POST, PUT, DELETE 등 요청의 목적을 명시합니다.
헤더(Header) 콘텐츠 타입, 인증 정보, 캐시 정책 등 메타데이터를 담습니다.
바디(Body) 실제 전송하는 데이터(JSON, HTML 등)가 위치합니다.
상태 코드(Status Code) 200(성공), 404(찾을 수 없음), 500(서버 오류) 등 응답 결과를 나타냅니다.

 

🛠️ 예시)

JavaScript

// 바닐라 자바스크립트로 GET 요청 보내기
fetch('https://api.woodycode.com/users/1')
  .then(response => {
    // 1. 상태 코드 확인 (200 OK인지)
    if (!response.ok) {
      throw new Error('네트워크 응답에 문제가 있습니다.');
    }
    // 2. 응답 헤더 확인 (Content-Type이 JSON인지)
    const contentType = response.headers.get('content-type');
    if (!contentType || !contentType.includes('application/json')) {
      throw new TypeError("Oops, we didn't get JSON!");
    }
    // 3. 바디 데이터 파싱
    return response.json(); 
  })
  .then(data => console.log('성공:', data))
  .catch(error => console.error('에러:', error));

(Stateless 및 쿠키/세션 내용 동일)


2. Stateless, 그리고 상태를 유지하기 위한 노력

HTTP는 Stateless(상태 없음) 프로토콜입니다. 즉, 서버는 이전 요청의 정보를 기억하지 않습니다. 이는 서버의 확장성을 높여주지만, 로그인 상태 유지 같은 기능을 구현하기 위해서는 별도의 메커니즘이 필요합니다.

  • 쿠키(Cookie): 클라이언트에 저장되는 작은 데이터 조각입니다.
  • 세션(Session): 서버에 사용자 정보를 저장하고, 쿠키를 통해 세션 ID를 주고받습니다.
  • 토큰(Token): JWT(JSON Web Token) 등을 사용하여 상태 정보를 암호화하여 주고받습니다.

3. 성능 최적화의 핵심, HTTP 캐싱

웹 애플리케이션의 성능을 높이는 가장 효과적인 방법 중 하나는 HTTP 캐싱을 잘 활용하는 것입니다. 캐싱을 통해 불필요한 네트워크 요청을 줄이고, 사용자에게 더 빠른 경험을 제공할 수 있습니다.

헤더 설명
Cache-Control 가장 중요한 캐시 제어 헤더입니다. max-age, no-cache, no-store 등의 지시자를 사용합니다.
ETag 리소스의 고유한 식별자(해시값)입니다. 리소스가 변경되었는지 확인하는 데 사용됩니다.
Last-Modified 리소스가 마지막으로 수정된 시간입니다.

❌ 잘못된 캐시 설정의 예

HTTP

Cache-Control: no-cache, no-store, must-revalidate

모든 리소스에 대해 캐시를 사용하지 않도록 설정하면, 사용자는 매번 모든 데이터를 다시 다운로드해야 하므로 성능이 저하됩니다.

✅ 바람직한 캐시 설정의 예

  • 정적 리소스(이미지, CSS, JS): 긴 max-age 값을 설정하고, 파일 이름에 해시값을 포함시켜 버전 관리를 합니다.
  • 동적 리소스(API 응답): 적절한 max-age 값을 설정하거나, ETag를 활용하여 조건부 요청을 보냅니다.

🛠️ 예시) Next.js에서 HTTP 캐싱 제어

RSC(React Server Components)의 핵심은 "데이터가 필요할 때 서버에서 직접 가져오는 것"입니다. Next.js는 이 fetch 요청을 서버단에서 강력하게 제어할 수 있는 기능을 제공합니다. 💡

JavaScript

// Next.js (App Router) Server Component 예시

async function getUser(id) {
  // ⭕ 바람직한 예: 이 요청은 1시간(3600초) 동안 캐싱됩니다.
  const res = await fetch(`https://api.woodycode.com/users/${id}`, {
    next: { revalidate: 3600 }, // SSG, ISR 느낌
  });

  // ❌ 지양해야 할 태도: 매 요청마다 데이터를 다시 가져옵니다. (캐싱 안 함)
  // const res = await fetch(`https://api.woodycode.com/users/${id}`, { cache: 'no-store' }); // SSR 느낌

  if (!res.ok) {
    throw new Error('데이터를 가져오지 못했습니다.');
  }

  return res.json();
}

export default async function Page({ params }) {
  const user = await getUser(params.id);
  
  return (
    <div>
      <h1>사용자: {user.name}</h1>
      {/* ... */}
    </div>
  );
}

4. 웹 보안의 기본, HTTPS

HTTPS(HyperText Transfer Protocol Secure)는 HTTP에 SSL/TLS 프로토콜을 더하여 데이터를 암호화하여 전송합니다.

  • 기밀성: 데이터가 도청되는 것을 방지합니다.
  • 무결성: 데이터가 변조되는 것을 방지합니다.
  • 인증: 통신 대상이 올바른지 확인합니다.

📡 (참고) HTTP의 진화: 1.1부터 3까지

우리가 프레임워크 선택 시 고민하는 성능 문제의 본질은 종종 HTTP 버전과 관련이 있습니다.

 

1️⃣ HTTP/1.1 (HOLB 문제)

: 한 번에 하나씩만 처리할 수 있어, 우리는 수백 개의 JS 파일을 하나로 뭉치는 '번들링'이미지를 하나로 합치는 '스프라이트' 기술에 목숨을 걸었습니다.

 

2️⃣ HTTP/2 (Multiplexing)

: 이제 한 연결에서 여러 요청을 병렬로 보낼 수 있습니다. 이제는 무거운 통파일 하나보다 적절히 쪼개진 모듈(ESM)을 전송하는 것이 초기 로딩 속도에 훨씬 유리합니다.

 

3️⃣ HTTP/3 (QUIC/UDP)

: 연결 설정 속도(RTT)를 극한으로 줄였습니다. 모바일 등 불안정한 네트워크 환경에서 우리 서비스가 끊기지 않게 하려면, 이제 인프라 단에서 HTTP/3 지원 여부를 체크하는 것이 필수입니다.


🚀 마치며: 다음 단계로의 초대

HTTP는 단순히 텍스트를 전달하는 통로가 아닙니다. 이 흐름을 이해해야만 비로소 "왜 내 앱이 느린지", "왜 보안 사고가 났는지"에 대한 근본적인 답을 찾을 수 있습니다.

 

[3줄 요약]

  1. HTTP는 Stateless 속성 덕분에 확장성을 얻었으며, 이를 보완하기 위한 인증 메커니즘 이해가 필수적임.
  2. 캐싱 전략은 네트워크 비용을 절감하고 UX를 극대화하는 가장 강력한 엔지니어링 도구임.
  3. HTTP/2와 3의 원리를 알아야 현대 웹의 모듈화 배포 전략을 제대로 세울 수 있음.

 

 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2026/06   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함