Можно ли кэшировать POST запросы и хорошая ли это идея
Что проверяют
Понимаете ли вы семантику HTTP-методов, а не только правило «кэшируем GET». Следом обычно спрашивают, как это сделать в ASP.NET Core и чем кэширование отличается от идемпотентности.
Как отвечать
Короткий ответ: по спецификации можно, на практике почти никогда не нужно, а где нужно, делают кэш на уровне приложения.
По RFC 9110 ответ на POST кэшируем, только если в нём есть явная информация о свежести и Content-Location, совпадающий с адресом запроса. Но такой ответ может обслужить последующий GET, а не повторный POST: POST небезопасен, и кэш обязан пропускать его к серверу. Браузеры и CDN поэтому POST на практике не кэшируют.
В ASP.NET Core:
- Response Caching Middleware и атрибут
[ResponseCache]: работают только с GET и HEAD, а атрибут сам по себе лишь выставляет заголовки; - Output Caching (
AddOutputCache): политика по умолчанию тоже берёт только GET и HEAD с ответом 200 и без аутентификации. POST можно включить своей реализациейIOutputCachePolicy, но это осознанный обход; IMemoryCache,IDistributedCacheс Redis,HybridCache: кэш данных внутри сервиса, где реальная задача обычно и решается.
Когда это оправдано: POST используется как чтение, потому что параметры не помещаются в URL, например сложный поиск или GraphQL. Ключ строится из хэша нормализованного тела плюс пользователя или тенанта, TTL короткий. Под такие случаи IETF продвигает метод QUERY, безопасный запрос с телом, но поддержка в инфраструктуре пока слабая.
Отдельно: хранение ответа по заголовку Idempotency-Key в платёжных API похоже на кэш, но задача другая. Это защита от двойного списания при повторе, а не ускорение.
Где спотыкаются
Отвечают «POST кэшировать нельзя», и всё. Это неточно по RFC и игнорирует реальные случаи с поиском через POST.
Строят ключ только из тела запроса. Два пользователя с одинаковым запросом получат данные друг друга, и это уже утечка.
Кэшируют запросы с побочным эффектом. Повторный заказ вернёт сохранённый ответ, и клиент решит, что заказ создан, хотя до сервера запрос не дошёл.