Какие HTTP-методы, как правило, не подлежат кэшированию и почему?

Ответ

Кэширование HTTP-ответов в основном применимо к безопасным (Safe) и идемпотентным (Idempotent) методам. Методы, изменяющие состояние сервера, обычно не кэшируются.

Методы, которые НЕ кэшируются (или кэшируются с крайними ограничениями):

Метод Почему не кэшируется
POST Создает новый ресурс. Каждый запрос потенциально уникален и приводит к изменению состояния сервера. Кэширование ответа POST (например, 201 Created) и его повторное использование для другого запроса привело бы к некорректному поведению.
PUT Хотя идемпотентен, он изменяет состояние ресурса. Кэширование ответа на PUT (например, 200 OK) и его выдача на последующий GET к тому же ресурсу может вернуть устаревшие данные, так как PUT их обновил. Кэшируются с большой осторожностью, обычно с Cache-Control: no-cache или max-age=0.
PATCH Частичное обновление, часто неидемпотентно. Как и PUT, изменяет ресурс, поэтому кэширование ответов не рекомендуется.
DELETE Удаляет ресурс. Ответ (например, 204 No Content или 200 OK) не имеет смысла кэшировать, так как последующий GET к этому URI должен вернуть 404 Not Found.

Методы, которые МОГУТ кэшироваться:

  • GET: Основной кандидат для кэширования. Ответы GET можно безопасно кэшировать, если они не содержат персональных или часто меняющихся данных.

    GET /api/products HTTP/1.1
    Host: example.com

    Ответ может включать заголовки для кэширования:

    HTTP/1.1 200 OK
    Cache-Control: public, max-age=3600
    Content-Type: application/json
    
    [{"id": 1, "name": "Product A"}]
  • HEAD: Аналогичен GET, кэшируются только заголовки ответа.

Правила кэширования определяются заголовками: Даже для GET кэширование может быть отключено, если ответ содержит:

Cache-Control: no-store          # Запрещает хранить ответ где бы то ни было.
Cache-Control: no-cache          # Ответ можно кэшировать, но перед использованием необходимо проверить его свежесть с сервером.
Cache-Control: private           # Ответ предназначен только для одного пользователя (например, с персональными данными).

Важность для тестирования:

  1. Тестирование кэширования: Проверять, что ответы на GET-запросы к статичным ресурсам возвращают корректные заголовки (Cache-Control, ETag, Last-Modified).
  2. Предотвращение ошибок: Убедиться, что ответы на POST, PUT, DELETE никогда не имеют заголовков, разрешающих их кэширование (public, max-age), чтобы избежать потери данных или некорректного поведения клиентов.
  3. Инвалидация кэша: Проверять механизмы инвалидации кэша (например, использование POST для изменения ресурса должно делать неактуальным кэш связанного GET-запроса).

Ответ 18+ 🔞

А, слушай, смотри, вот эта вся хуйня с кэшированием HTTP-ответов — это, блядь, не просто так, наобум. Тут, сука, железная логика, как у Герасима из рассказа — либо так, либо нихуя.

Вот представь, сервер — это такой здоровый, молчаливый чувак, а кэш — это его собачка Муму, которая запоминает, что он сказал в прошлый раз, чтобы не орать одно и то же постоянно. Но, блядь, не все слова собачке доверять можно!

Кому НЕЛЬЗЯ доверять, блядь, собачке-кэшу (она запомнит и потом нахуярит):

Метод В чём, сука, подвох?
POST Это ж, ёпта, создание нового! Каждый раз — уникальный пиздёныш. Если собачка запомнит ответ "201 Created" и будет его всем подряд тыкать, получится, что мы один заказ на все сто раз продублируем. Пиздец и разорение.
PUT Хотя он и идемпотентный (ты его десять раз шлёшь — результат как от одного), он состояние меняет! Допустим, ты обновил цену. Собачка запомнила старый ответ "200 OK" и потом, когда ты захочешь посмотреть новую цену (GET), она тебе старую из своей пасти вытащит. Во какие, блядь, нахуй, распиздяйства!
PATCH Это вообще, хитрая жопа, частичное обновление. Часто даже не идемпотентное. Меняет ресурс — значит, кэшу на него доверия ебать ноль.
DELETE Ну тут вообще пиздец очевидный. Удалил ты товар, получил "204 No Content". Если это в кэш записать, то потом, когда кто-то попробует получить (GET) этот товар, кэш радостно выдаст "Всё чисто, братан!", хотя на самом деле там уже 404 Not Found и пустота.

А кому МОЖНО, блядь?

  • GET: Вот это наш король, главный кандидат! Запрос данных, нихуя не меняет. Идеально для собачки.

    GET /api/products HTTP/1.1
    Host: example.com

    И сервер ему в ответ, такой: "На, собачка, запомни это на час":

    HTTP/1.1 200 OK
    Cache-Control: public, max-age=3600
    Content-Type: application/json
    
    [{"id": 1, "name": "Product A"}]
  • HEAD: Это как GET, но только шапку (заголовки) просит. Тоже можно, но только шапку и запоминать.

Но и тут, сука, не всё просто! Даже GET можно так заклеймить, что кэш и близко не подойдёт. Смотри, какие бывают отмазки:

Cache-Control: no-store          # Вообще, блядь, не храни. Нигде. Забудь, что я тебе это говорил.
Cache-Control: no-cache          # Ну, запомнить можно, но перед тем как кому-то отдать — позвони на сервер, спроси, не передумал ли я.
Cache-Control: private           # Это только для одного юзера (типа, его личный профиль). Не смей другим показывать, манда с ушами!

И что, блядь, со всем этим делать тестировщику?

  1. Проверяй, кто кэшируется: Гоняй GET-запросы к статике (картинки, списки товаров). Смотри, чтобы в ответе были эти самые Cache-Control, ETag или Last-Modified. Чтобы собачка знала, что ей делать.
  2. Лови говнокод: Твоя святая обязанность — орать благим матом, если в ответе на POST, PUT или DELETE вдруг вылезет Cache-Control: public, max-age=100500. Это пизда, это прямой путь к потере данных и пиздецу в продакшене. Нельзя!
  3. Следи за инвалидацией: Вот, допустим, ты через POST создал новый отзыв. Так, блядь, проверь, что кэш на страницу товара (которая через GET отдаётся) после этого стал невалидным. Чтобы новый отзыв сразу был виден, а не через пиздюлей пользователю приходилось кэш сбрасывать. Вот это и есть — волнение ебать, правильная работа!