Одним из немногих ограничений, которые имеет REST, является ограничение кеширование . Ограничения, как следует из названия, согласно Филдингу, не вариант , хотя он говорил о гипермедиа в этом контексте. Хотя общее правило применимо и здесь.
Кэширование позволяет локальным или промежуточным приложениям, так называемым кешам, хранить ответ определенного URI в течение определенного промежутка времени, и если дополнительный безопасный запрос для того же URI попадет в кеш, кеш будет обслуживать клиента с его сохраненный ответ, а не маршрутизация запроса на сервер.
В случае вашего истечения срока действия вам также необходимо включить мысли об истечении срока действия таких кэшированных значений, в противном случае кеши могут по-прежнему обслуживать клиентов с данными, которые в дальнейшем не должны существовать.
HTTP подробно описывает кэширование в RFC 7234 , а ответы могут указывать кешу, как долго ресурс должен считаться свежим через заголовок Cache-Control или Истекает заголовок. Если присутствуют оба, побеждает первый. Например, заголовок ответа, такой как Cache-Control: max-age=3600
, определяет, что ответ должен считаться свежим на срок до 3600 секунд, в то время как Expires
должен использовать формат даты и времени, указанный в RFC 7231 , такой как Expires: Fri, 24 May 2019 05:20:00 CET
.
К сожалению, в RFC 7234 не говорится о том, как клиент может активно устанавливать такую директиву, поскольку это считается задачей сервера. Cache-Control
предоставляет некоторые заголовки запроса , хотя это больше указывает на то, что клиент либо примет или не примет устаревшие данные, но не указывает серверу установить соответствующую дату истечения срока действия. Обычно, если клиент не хочет, чтобы определенный ресурс был в дальнейшем доступен, он должен DELETE
ресурс. Если вы прочитаете DELETE , вы можете быть удивлены тем, что это на самом деле не гарантирует, что ресурс когда-либо будет вообще удален. Все это говорит о том, что после успешной обработки такого запроса сопоставление URI с ресурсом удаляется. Доступен ли один и тот же ресурс через другой URI или нет, это не отдельная история. «Настройка» DELETE
с каким-либо параметром для удаления ресурса через определенное время может работать для вашего API, хотя может быть непонятным для различных типов API, поэтому в общем случае это не рекомендуется.
При использовании PATCH
информация о метке времени истечения должна быть частью самого ресурса. Обычно такая информация считается метаданными ресурса, а не фактическими данными или их частью. Поэтому я тоже не одобряю PATCH
, хотя это явно взвешенный подход.
Если все другие методы HTTP не соответствуют требованиям, следует принять POST , так как здесь сервер будет обрабатывать запрос в соответствии со своей собственной семантикой. Он может применять разные эвристики и при получении разных полезных нагрузок на одну и ту же конечную точку. Если вам нужно разработать такую функцию в Интернете, у вас может быть страница редактирования записи, где у вас есть возможность установить срок действия. После нажатия кнопки отправки формы ваш браузер выполняет запрос POST
, включая дату истечения срока действия, и сервер будет знать, что делать, основываясь на определенных эвристиках, доступных на сервере. То есть наличие в запросе поля даты истечения срока действия может дать серверу указание поставить в очередь удаление записи, обновить метаданные даты истечения срока действия целевого ресурса и вернуть обновленный заголовок Cache-Control: max-age=...
или Expires: ...
для входящих запросов. сообщать кешам о том, что не отправлены кэшированные ответы этого ресурса после этого момента времени.
Обычно небезопасные операции, такие как POST
, PUT
или DELETE
, делают недействительными кэшированные ответы целевого ресурса по умолчанию, в случае, когда два пользователя выполняют кешируемые GET
запросы против сервер, имеющий промежуточный кэш, который отличается от промежуточного кеша другого пользователя, и пользователь 1 теперь истекает ресурс источника, может быть случай, когда пользователь 2 все еще будет обслуживаться «своим» промежуточным кешем для цели ресурс, даже несмотря на то, что ресурс уже был удален на исходном сервере, поскольку его промежуточный кэш по-прежнему считает ответ достаточно свежим и поэтому использует значение 2 с этим сохраненным ответом. Кэшированный ответ целевого URI в кеше пользователя 1 уже должен был быть удален первоначальным запросом POST
, но также любой в конечном итоге кэшируемый ответ мог бы вернуть обновленный заголовок кэша и, таким образом, привести к истечению срока действия в указанный момент времени. Поэтому важно установить значения времени для кэша не слишком высокими в будущем, но и не короткими, чтобы кэширование стало бесполезным.
Для ресурсов, которые могут быть критически важны для удаления и не обслуживаются кэшами, для предотвращения вышеупомянутого случая, вероятно, лучше всего указать Cache-Control: no-cache
в целом, чтобы такие записи не сохранялись в кэшах далее, а запросы напрямую обрабатывается самим API / сервером.
Чтобы подвести итог этого поста, что-то вроде момента истечения срока действия следует рассматривать как метаданные ресурса, а не как основные данные. Хотя DELETE
на первый взгляд может звучать замечательно, через некоторое время он не поддерживает удаление, и другой API может выполнить такой запрос немедленно, кроме того, что вообще не гарантирует реального удаления этого ресурса. POST
, как универсальный набор инструментов HTTP, или другие операции HTTP, такие как PUT
или PATCH
, также могут быть использованы здесь, даже если последние "работают" при условии, что тело запроса принадлежит к фактическим данным ресурса. Вам также следует рассмотреть возможность кэширования в вашем проекте и использовать Cache-Control: max-age=...
или Expires: ...
, если ваш ресурс не критичен, или Cache-Control: no-cache
в случае ресурсов, которые никогда не должны (по какой-либо причине) возвращать устаревшую информацию клиентам. Независимо от используемого вами метода HTTP, вам также следует подумать о том, как сервер разрешает клиенту устанавливать эту опцию в целом. Как и в Интернете, решение на основе форм позволяет избежать внеполосной информации и, таким образом, упрощает взаимодействие с API в целом, поскольку вся информация уже предоставлена или доступна по дополнительным ссылкам.