ETag & Caching
ETag (Entity Tag), EK RESPONSE HEADER hai — RESOURCE ke, CURRENT STATE ka, EK UNIQUE, HASH-BASED, IDENTIFIER. CLIENT, IS ETAG ko, STORE kar leta hai. AGLI REQUEST mein, CLIENT, If-None-Match HEADER mein, YE STORED ETag, BHEJTA hai.
AGAR, RESOURCE, CHANGE NAHI HUA (SERVER ka, CURRENT ETag, SAME hai), SERVER, 304 Not Modified (BINA, BODY ke) RETURN karta hai — BANDWIDTH aur PROCESSING TIME, DONO, BACHTE HAIN. AGAR, RESOURCE, CHANGE HUA hai, SERVER, NAYA DATA, NAYE ETag ke SAATH, RETURN karta hai (200 OK).
@GetMapping("/{id}")
public ResponseEntity<ProductDto> getProduct(
@PathVariable Long id, WebRequest request) {
Product product = productService.findById(id);
String etag = String.valueOf(product.getVersion()); // ya hash of content
if (request.checkNotModified(etag)) {
return null; // Spring, AUTOMATICALLY, 304 Not Modified, return kar deta hai
}
return ResponseEntity.ok().eTag(etag).body(toDto(product));
}
// FIRST request:
// GET /api/products/1 → 200 OK, ETag: "3"
// SECOND request (client, stored ETag bhejta hai):
// GET /api/products/1
// If-None-Match: "3"
// → 304 Not Modified (agar resource, CHANGE NAHI hua) — koi BODY nahi- ETag = resource ke CURRENT STATE ka, unique identifier
- If-None-Match + 304 Not Modified = bandwidth/processing, DONO bachte hain
- If-Match, PUT/PATCH mein, OPTIMISTIC concurrency control ke liye, USE ho sakta hai
STRONG, ETag (jaise, "abc123"), BYTE-FOR-BYTE, IDENTICAL, CONTENT, GUARANTEE karta hai. WEAK, ETag (jaise, W/"abc123"), "SEMANTICALLY, EQUIVALENT" CONTENT, INDICATE karta hai (MINOR, DIFFERENCES, jaise, WHITESPACE, OK HAIN) — WEAK, ETags, GENERATE karna, EASIER/FASTER, HOTA hai.
- Strong ETag = byte-for-byte, IDENTICAL, content
- Weak ETag (W/"...") = SEMANTICALLY, equivalent — generate karna, FASTER
Cache-Control: max-age=3600, ETag ke SAATH, COMBINE hota hai — max-age, BATATA hai, "KITNI, DER TAK, BINA, SERVER SE, PUCHE, CACHED, VERSION, USE karo". EK, GHANTE ke, ANDAR, BROWSER, SERVER ko, PUCHEGA HI NAHI — max-age, EXPIRE hone ke, BAAD, ETag SE, VALIDATE karega.
return ResponseEntity.ok()
.cacheControl(CacheControl.maxAge(1, TimeUnit.HOURS))
.eTag(etag)
.body(product);