Cache-Control каже клієнтам і проміжним кешам (CDN, проксі), чи можна зберігати відповідь і як довго:
Cache-Control: public, max-age=300 # будь-хто може кешувати 5 хвилин
Cache-Control: private, max-age=60 # лише браузер користувача
Cache-Control: no-store # не зберігати взагалі (персональні, чутливі дані)
Cache-Control: no-cache # зберігати, але перевіряти перед кожним використанням
Умовні запити й ETag. Сервер віддає «відбиток» версії ресурсу:
HTTP/1.1 200 OK
ETag: "a1b2c3"
Cache-Control: no-cache
Наступного разу клієнт питає «чи змінилося?»:
GET /products/42
If-None-Match: "a1b2c3"
Якщо ні - 304 Not Modified без тіла. Економиться трафік і серіалізація, хоча сам запит до сервера відбувається. Аналог за датою - Last-Modified / If-Modified-Since.
ETag для конкурентних змін: If-Match: "a1b2c3" при PUT/PATCH - оновити лише якщо ресурс не змінився з того часу, як клієнт його прочитав. Інакше 412 Precondition Failed. Це оптимістичне блокування на рівні HTTP, захист від загублених оновлень.
Нюанси:
- Персональні відповіді не можна позначати
public: CDN віддасть дані одного користувача іншому. Для відповідей, що залежать від токена, -privateабоno-store. Varyкаже кешу, від яких заголовків запиту залежить відповідь:Vary: Accept-Language,Vary: Authorization.- ETag має бути дешевим: якщо для нього треба зібрати всю відповідь, економиться лише трафік. Краще брати версію з бази (
updated_at, лічильник версії). - Інвалідація - найскладніше: короткий
max-ageплюсstale-while-revalidateчасто практичніші за спроби точно скидати кеш.