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

{% 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/>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.system-analyst-base.ru/hard-skills/integracii/vidy-integracii/sinkhronnoe-vzaimodeistvie/rest/restful-principy/keshirovanie.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
