ETAG

빙그르·2024년 1월 24일
0

SPRING

목록 보기
7/9

ETAG

알아보니 단점이 치명적이라 잘 안 쓰는것 같았다.
단점 : ETag의 문제점은 해당 값이 서버당 하나이기 때문에 여러 서버로 운영되는 서비스일 경우 값이 일치하지 않게 된다.

HTTP response의 ETag(Entity Tag) 헤더는 주로 다음과 같은 이유로 사용됩니다.

  • 캐싱 효율 최적화: ETag를 사용하면 클라이언트는 캐시된 리소스가 변경되었는지 여부를 쉽게 확인 가능
  • 조건부 요청: 클라이언트는 ETag를 이용해 If-Match, If-None-Match header를 통해 조건부 GET 요청 가능
  • 네트워크 트래픽 줄이기: 캐시나 조건부 요청을 통해 불필요한 데이터 전송量 줄일 수 있음
  • 리소스 변경 감지: ETag는 리소스 버전 관리에 사용될 수 있음
  • 병행 제어: ETag를 사용하면 동시 업데이트 문제를 방지하는 데 도움됨
  • 검증: ETag는 메시지 무결성 검증에 사용될 수 있음
  • 대용량 리소스: 대용량 리소스의 경우 전체 내용 대신 ETag를 사용하여 효율 증대

결론적으로 ETag는 HTTP 캐싱, 조건부 요청, 리소스 버전 관리 등을 효과적으로 수행하기 위한 목적으로 주로 사용됩니다.

Controller

@RestController
public class BeanController {
    @GetMapping(value = "/etag")
    public ResponseEntity<String> findByIdWithCustomEtag() {
        String json = "{" +
                "  \"name\": \"John Doe\"," +
                "  \"age\": 30," +
                "  \"address\": \"123 Main Street, Anytown, CA 12345\"" +
                "}";
        return ResponseEntity.ok()
                .eTag(Long.toString(123))
                .body(json);
    }
}

etagFilter

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.filter.ShallowEtagHeaderFilter;

@Configuration
public class ETagHeaderFilter {

    @Bean
    public ShallowEtagHeaderFilter shallowEtagHeaderFilter() {
        return new ShallowEtagHeaderFilter();
    }
}

test

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@SpringBootTest
@AutoConfigureMockMvc
class BeanControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @Test
    void etagTest() throws Exception {
        // Given
        String url = "/etag";

        // 첫 번째 요청을 보낸다.
        MvcResult mvcResult = this.mockMvc.perform(get(url))
                .andDo(print())
                .andExpect(status().isOk()) // 첫 요청이기 때문에 200 OK
                .andExpect(header().exists("ETag")) // ETag를 사용하고 있기 때문에 header가 ETag를 가지고 있는지 확인해준다.
                .andReturn();

        String etag = mvcResult.getResponse().getHeader("ETag");

        // 두 번째 요청을 보낸다.
        this.mockMvc.perform(get(url).header("If-None-Match", etag)) // 응답받은 ETag를 해더에 담아 보낸다.
                .andDo(print())
                .andExpect(status().isNotModified()) // 유효성 검사를 하고 변경이 안되었기때문에 304 Not Modified
                .andExpect(header().exists("ETag"))
                .andReturn();
    }
}

0개의 댓글