HTTP의 ETag에 대해서 설명해주세요.
분야: 프론트엔드
ETag(Entity Tag)는 HTTP 프로토콜에서 사용되는 헤더로, 웹 리소스의 특정 버전을 식별하는 고유한 식별자입니다.
서버가 클라이언트에게 리소스를 전송할 때 ETag 헤더를 포함시키고, 클라이언트는 이후 요청 시 If-None-Match 헤더에 이 값을 포함하여 조건부 요청을 보낼 수 있습니다.
ETag의 주요 목적은 캐싱 효율성을 높이는 것입니다. 클라이언트가 이미 가지고 있는 리소스와 서버의 현재 버전이 동일한지 확인할 수 있어, 변경되지 않았다면 전체 콘텐츠를 다시 다운로드하지 않고 304 Not Modified 응답을 받습니다. 이를 통해 네트워크 트래픽과 서버 부하를 줄일 수 있습니다.
Last-Modified 헤더와 비슷한 역할을 하지만, 타임스탬프 기반이 아닌 콘텐츠 기반으로 동작합니다. 그렇기 때문에 ETag는 1초 내에 여러 변경이 있거나 시간 기반 비교가 적합하지 않은 상황에서 더 정확한 캐싱을 제공합니다.
ETag 값은 보통 리소스의 내용에 기반한 해시값이나 버전 번호로 생성되며, Strong ETag와 Weak ETag(W/ 접두사 사용) 두 종류로 나뉩니다. Strong ETag는 바이트 단위까지 정확히 일치해야 하고, Weak ETag는 의미적으로 동등하면 일치하는 것으로 간주합니다.
ETag를 Cache-Control 헤더와 함께 사용하기도 하나요? 🤔
ETag와 Cache-Control은 서로 보완적인 관계에 있으며, 함께 사용하면 더 효과적인 캐싱 전략을 구현할 수 있습니다.
Cache-Control은 리소스의 캐싱 정책을 직접적으로 지정하는 헤더로, 캐시 가능 여부, 유효 기간, 재검증 요구사항 등을 설정합니다. 반면 ETag는 리소스의 변경 여부를 확인하는 메커니즘을 제공합니다.
실제 프로젝트에서는 두 헤더를 다음과 같이 조합하여 사용할 수 있습니다.
Cache-Control: max-age=31536000
ETag: "abc123"
정적 리소스(이미지, CSS, JS 등)의 경우, 이와 같이 설정하면 1년간 클라이언트 캐시를 사용하되, 리소스 갱신 시(ex. 배포) ETag가 변경되어 새 버전을 받아갑니다. 파일명에 해시를 포함시키는 방식으로도 구현할 수 있습니다.
Cache-Control: no-cache
ETag: "xyz789"
자주 변경되는 API 응답의 경우, 이처럼 no-cache 설정으로 매번 서버에 재검증을 요청하게 하되, ETag를 통해 콘텐츠가 변경되지 않았다면 304 응답으로 데이터 전송을 줄일 수 있습니다.