1.10. HTTP 캐싱

편집일시: 2021-04-15 11:40 조회수: 189 댓글수: 0
[Web MVC](https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-caching) HTTP 캐싱은 Web 어플리케이션의 성능을 크게 개선시켜 준다. HTTP 캐싱은 `Cache-Control` 응답 헤더와 `Last-Modified`와 `ETag`와 같이 이어지는 조건부 요청 헤더를 중심으로 동작한다. `Cache-Control`는 프라이빗 (브라우저 등) 및 퍼블릭(프록시 등)의 캐시가 응답을 캐시하여 재사용하는 방법을 권고한다. 컨텐츠가 변경되지 않은 경우, `ETag` 헤더를 사용하여 본문(body)이 없는 304 (NOT_MODIFIED)가 될 조건부 요청을 만든다. `ETag`는 `Last-Modified` 헤더보다 정교한 것으로 대체 버전으로 볼 수 있다. 이번 섹션에서는 Spring WebFlux에서 사용 가능한 HTTP 캐싱 관련 옵션에 대해 설명한다. ## 1.10.1. `CacheControl` [Web MVC](https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-caching-cachecontrol) [`CacheControl`](https://docs.spring.io/spring-framework/docs/5.3.5/javadoc-api/org/springframework/http/CacheControl.html) 는 `Cache-Control` 헤더에 관련 설정 구성을 지원하고, 많은 곳에서 인수로 허용된다. - [컨트롤러 - Controllers](https://docs.spring.io/spring-framework/docs/current/reference/html/web-reactive.html#webflux-caching-etag-lastmodified) - [정적 자원 - Static Resources](https://docs.spring.io/spring-framework/docs/current/reference/html/web-reactive.html#webflux-caching-static-resources) [RFC 7234](https://tools.ietf.org/html/rfc7234#section-5.2.2)는 `Cache-Control` 응답 헤더의 가능한 모든 지시어(directive)를 기술한다. `CacheControl` 유형은 다음의 예와 같이 일반적인 시나리오에 초점을 맞춘 사례 중심의 접근 방식을 취한다. Java ``` // Cache for an hour - "Cache-Control: max-age=3600" CacheControl ccCacheOneHour = CacheControl.maxAge(1, TimeUnit.HOURS); // Prevent caching - "Cache-Control: no-store" CacheControl ccNoStore = CacheControl.noStore(); // Cache for ten days in public and private caches, // public caches should not transform the response // "Cache-Control: max-age=864000, public, no-transform" CacheControl ccCustom = CacheControl.maxAge(10, TimeUnit.DAYS).noTransform().cachePublic(); ``` Kotlin ``` // Cache for an hour - "Cache-Control: max-age=3600" val ccCacheOneHour = CacheControl.maxAge(1, TimeUnit.HOURS) // Prevent caching - "Cache-Control: no-store" val ccNoStore = CacheControl.noStore() // Cache for ten days in public and private caches, // public caches should not transform the response // "Cache-Control: max-age=864000, public, no-transform" val ccCustom = CacheControl.maxAge(10, TimeUnit.DAYS).noTransform().cachePublic() ``` ## 1.10.2. 컨트롤러 [Web MVC](https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-caching-etag-lastmodified) 컨트롤러는 HTTP 캐싱의 명시적인 지원을 추가 할 수 있다. 리소스 `lastModified` 또는 `ETag` 값은 조건부 요청 헤더와 비교하기 전에 계산해야 하므로 이런 방식을 추천한다. 다음의 예와 같이, 컨트롤러에 `ETag`, `Cache-Control` 설정을 `ResponseEntity`에 추가 할 수 있다. Java ``` @GetMapping("/book/{id}") public ResponseEntity<Book> showBook(@PathVariable Long id) { Book book = findBook(id); String version = book.getVersion(); return ResponseEntity .ok() .cacheControl(CacheControl.maxAge(30, TimeUnit.DAYS)) .eTag(version) // lastModified is also available .body(book); } ``` Kotlin ``` @GetMapping("/book/{id}") fun showBook(@PathVariable id: Long): ResponseEntity<Book> { val book = findBook(id) val version = book.getVersion() return ResponseEntity .ok() .cacheControl(CacheControl.maxAge(30, TimeUnit.DAYS)) .eTag(version) // lastModified is also available .body(book) } ``` 위의 예제에서는 조건부 요청 헤더에 비해 콘텐츠가 변경되지 않았다면, 빈 본문를 포함한 304 (NOT_MODIFIED) 응답이 전송된다. 그렇지 않으면, `ETag` 및 `Cache-Control` 헤더가 응답에 추가된다. 다음의 예와 같이 컨트롤러의 조건부 요청 헤더에 체크를 할 수도 있다. Java ``` @RequestMapping public String myHandleMethod(ServerWebExchange exchange, Model model) { long eTag = ... // (1) if (exchange.checkNotModified(eTag)) { return null; // (2) } model.addAttribute(...); // (3) return "myViewName"; } ``` Kotlin ``` @RequestMapping fun myHandleMethod(exchange: ServerWebExchange, model: Model): String? { val eTag: Long = ... // (1) if (exchange.checkNotModified(eTag)) { return null // (2) } model.addAttribute(...) // (3) return "myViewName" } ``` - (1) 응용 프로그램의 고유 방식으로 계산한다. - (2) 응답은 304 (NOT_MODIFIED)로 설정한다. 더 이상 다른 처리는 하지 않는다. - (3) 요청 처리를 계속한다. 조건부 요청을 ` eTag` 값, `lastModified` 값 또는 둘 모두에 대해 확인하기 위해 3개의 변형이 있다. 조건부 `GET`과 `HEAD` 요청인 경우, 응답을 304 (NOT_MODIFIED)에 설정할 수 있다. 조건부 `POST`, `PUT`, `DELETE`의 경우 대신 응답을 412 (PRECONDITION_FAILED)로 설정하여 동시 변경을 방지 할 수 있다. ## 1.10.3 정적 리소스 [Web MVC](https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-config) 최적의 성능을 얻으려면, `Cache-Control`와 조건부 응답 헤더에서 정적 리소스를 제공해야 한다. [정적 리소스](https://docs.spring.io/spring-framework/docs/current/reference/html/web-reactive.html#webflux-config-static-resources) 구성 섹션을 참조해라.

이전 글 : 1.9. View Technologies
다음 글 : 1.11. WebFlux Config