java 35 lines · 6 steps

HTTP caching with ETags in Spring

A shallow ETag filter plus Cache-Control headers cut bandwidth by letting clients revalidate and reuse product responses.

Explained by highlit
1@Configuration
2public class WebConfig {
3 
4 @Bean
5 public FilterRegistrationBean<ShallowEtagHeaderFilter> shallowEtagHeaderFilter() {
6 FilterRegistrationBean<ShallowEtagHeaderFilter> registration =
7 new FilterRegistrationBean<>(new ShallowEtagHeaderFilter());
8 registration.addUrlPatterns("/api/products/*");
9 registration.setName("etagFilter");
10 registration.setOrder(Ordered.HIGHEST_PRECEDENCE + 10);
11 return registration;
12 }
13}
14 
15@RestController
16@RequestMapping("/api/products")
17class ProductController {
18 
19 private final ProductRepository productRepository;
20 
21 ProductController(ProductRepository productRepository) {
22 this.productRepository = productRepository;
23 }
24 
25 @GetMapping("/{id}")
26 public ResponseEntity<ProductView> getProduct(@PathVariable Long id) {
27 Product product = productRepository.findById(id)
28 .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));
29 
30 ProductView body = ProductView.from(product);
31 return ResponseEntity.ok()
32 .cacheControl(CacheControl.maxAge(Duration.ofMinutes(5)).cachePublic())
33 .body(body);
34 }
35}
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1A shallow ETag filter hashes the rendered response body so unchanged content returns 304 without re-sending it.
  2. 2Scoping a FilterRegistrationBean to a URL pattern keeps expensive filters off routes that don't need them.
  3. 3Cache-Control and ETag work together: one sets freshness lifetime, the other enables cheap revalidation after it expires.

Related explainers

Share this explainer

Here's the card — post it anywhere.

HTTP caching with ETags in Spring — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code