> For the complete documentation index, see [llms.txt](https://docs.system-analyst-base.ru/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.system-analyst-base.ru/hard-skills/integracii/vidy-integracii/sinkhronnoe-vzaimodeistvie/rest/restful-principy/keshirovanie.md).

# Кеширование

{% hint style="info" %}
**Кэширование** — это возможность хранить копии часто используемых данных в нескольких местах по пути запроса-ответа.
{% endhint %}

Кэширование хранит и извлекает данные из программного или аппаратного компонента. Когда клиент (например, браузер) отправляет запрос REST API, он может сохранить ответ API в кеше. В следующий раз, когда клиент инициирует этот запрос, он получит более быстрый ответ, поскольку серверу не придется обрабатывать его заново. Кэширование жизненно важно для каждого API. Это экономит накладные расходы и сокращает время отклика.

## Зачем использовать кэширование?

* **Это сокращает время ответа:** когда клиент неоднократно инициирует API без инструкций по кэшированию, время ответа API остается одинаковым независимо от того, изменяются данные или нет. API с инструкциями по кэшированию ускоряет время ответа, поскольку первый запрос клиента сохраняется в кеше для будущих запросов. Пока срок действия данных не истек или не изменился, результаты API можно использовать снова и снова.
* **Это снижает нагрузку на сервер:** кэширование действует как промежуточное программное обеспечение между клиентом и сервером. Он перехватывает запрос от клиента и обрабатывает данные запроса. Если данные ответа находятся в кеше, клиент может получить данные без участия сервера.
* **Это повышает производительность вашего приложения**: поскольку сервер освобождается от повторной обработки кэшированных данных, вместо этого он может выполнять другие операции.

### Кеширование в REST

Кэшируемость — одно из архитектурных ограничений REST.

* **GET-** запросы должны кэшироваться по умолчанию — до тех пор, пока не возникнет особое условие. Обычно браузеры рассматривают все запросы GET как кэшируемые.
* **POST-** запросы не кэшируются по умолчанию, но их можно сделать кэшируемыми, если к ответу добавлен `Expires` заголовок или `Cache-Control`  заголовок с директивой, явно разрешающей кэширование.
* Ответы **PUT** и **DELETE** запросы вообще не кэшируются.

## Как управлять кешем

Ниже приведены основные заголовки HTTP-ответов, которые мы можем использовать для управления поведением кэширования:

### Expires

HTTP- заголовок `Expires` указывает до какого времени можно хранить ресурс в кэш. По истечении этого времени кэшированное представление считается устаревшим и должно быть повторно проверено на исходном сервере.

### Last-Modified

Заголовок `Last-Modified` указывает, когда связанный ресурс был последний раз изменен. Этот заголовок используется в качестве средства проверки, чтобы определить, совпадает ли полученный ответ сервера с ранее сохраненным ресурсом в кэше клиента.

### ETag

Заголовок `ETag` — это токе&#x43D;*,* который генерируется сервером на основе содержимого ресурса и позволяет однозначно идентифицировать его состояние. Если ресурс по данному URL-адресу изменяется,  сервер создет новый токен `Etag`. Сравенение старого и нового токена от сервера поможет определить, являются ли два ресурса одинаковыми и нужно ли обновлять кэш на клиенте.

### Cache-Control

Значение заголовка `Cache-Control` содержит одну или несколько директив, разделенных запятыми . Эти директивы определяют, кэшируется ли ответ, и если да, то кем и как долго, например, `max-age` или `s-maxage` директивы.

Например, если вы установите значение `Cache-Control` в заголовке ответа API на `max-age=60`, браузер будет хранить кэш в течение шестидесяти секунд.

## Инвалидация кеша

{% hint style="info" %}
**Инвалидация кэша** — это процесс, при котором компьютерная система объявляет записи кэша недействительными и удаляет или заменяет их. Если данные изменяются, они должны быть инвалидированы в кэше, в противном случае это может привести к несогласованному поведению приложения.
{% endhint %}

### Инвалидация по TTL

При сохранении данных  в кэш для них устанавливается время жизни (TTL - time to live) и данные будут автоматически удалены через это время.&#x20;

Основная проблема заключается в подборе TTL. Если TTL слишком короткий, то запись может “протухнуть” и стать недействительной раньше, чем обновление было бы необходимо, что приведет к отправке повторного запроса в источник данных. Если TTL слишком длинный, то запись может содержать устаревшие данные, что может привести к ошибкам или неправильной работе приложения. Обычно ответ на этот вопрос подбирается эмпирическим путем.

### Инвалидация по событию

При таком подходе данные инвалидируют при наступлении некого события – обычно это обновление данных в источнике. В качестве события для инвалидации данных может выступать время последней модификации данных. Такой способ используется в HTTP.

Источники:

* <https://stellate.co/blog/deep-dive-into-caching-rest-apis>
* <https://restfulapi.net/caching/>
* <https://ml-system-design.ru/courses/system-design/learn/2.7>
* <https://habr.com/ru/articles/734660/>
