Соображения по кэшированию для коллекции REST и отдельных элементов

#rest #http-caching

#rest #http-кэширование

Вопрос:

Я работаю над новым REST-ful API, основным / единственным потребителем которого будет клиент smart / non-web-browser. У меня есть ресурс коллекции, который поддерживается / обновляется фоновыми процессами, а не самим клиентом. Единственным типом контента, необходимым для первой итерации, является JSON. URI — это что-то вроде:

  • /items/ — Ресурс, представляющий коллекцию элементов.
  • /items/123 — Ресурс, представляющий отдельный элемент с идентификатором 123 .

Хотя клиент не будет создавать новые элементы или обновлять коллекцию для добавления / удаления элементов, он будет обновлять некоторые значения в отдельных элементах. Мой план состоит в том, чтобы использовать HTTP PATCH для обновления ресурсов элементов, используя мой собственный формат исправления JSON.

Будет много одновременных клиентов, читающих элементы, и одновременные обновления для разных элементов, со случайными одновременными обновлениями одного и того же элемента, и, хотя допускается определенная степень «возможной согласованности», я хотел бы разработать это как можно более «дружественным к кэшу» способом. Читая RFC для ИСПРАВЛЕНИЯ, я вижу, что при успешном ответе на ИСПРАВЛЕНИЕ кэш URI-запроса должен быть обновлен ответом, если он есть. Вопрос сводится к:

Должен ли я:

А) включить полное представление отдельных элементов в /items/ представление JSON ресурса коллекции и отправить ИСПРАВЛЕНИЕ в /items/ URI и включить элемент для обновления в формате исправления?

ПЛЮСЫ:

  • Это позволяет клиенту не выполнять N количество запросов только для отображения списка ресурсов
  • позволяет любому кешу items быть недействительным, когда клиент обновляет элемент.

МИНУСЫ:

  • Для меня это не так «чисто», поскольку я на самом деле обновляю не коллекцию, а отдельный элемент.
  • Это делает недействительным кэш всей коллекции, а не кэш одного элемента, который изменился.

или

Б) В JSON-представлении коллекции ресурсов включите только ссылки на включенные элементы и попросите клиента запросить отдельные элементы после обнаружения, какие из них находятся в коллекции. HTTP-ИСПРАВЛЕНИЕ будет отправлено в URI отдельного элемента (например /items/123 )

ПЛЮСЫ:

  • Независимое кэширование ресурсов коллекции и элементов. ИСПРАВЛЕНИЕ отдельного элемента может должным образом аннулировать кэш только этого элемента.
  • API понятнее, поскольку вы выпускаете HTTP-ИСПРАВЛЕНИЕ для конкретного элемента, который хотите обновить.

МИНУСЫ:

  • Не позволяет выполнять пакетные обновления элементов. В настоящее время это вообще не является обязательным требованием, и я не предвижу этого в будущем, но только ретроспектива составляет 20-20.
  • Требуется, чтобы клиент отправлял N 1 запросы для отображения полного списка элементов.

Ответ №1:

Я бы выбрал B. Но ваши клиенты обычно запрашивают всю коллекцию (я имею в виду, нужна ли им коллекция)? если нет A , опция будет генерировать слишком много трафика. И аннулирование кэша происходит для всех элементов (поскольку они находятся в коллекции).

Если ваши клиенты в основном получают всю коллекцию, то A параметр запроса для конкретного элемента также является опцией.

Комментарии:

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

2. Если вы используете опцию A с параметром запроса, для обновлений кажется грязным выполнять ИСПРАВЛЕНИЕ HTTP /items/?id=123 , поскольку элемент сам по себе является надежным ресурсом, но, возможно, мне нужно просто отпустить это…

3. Ну, я сам не люблю HTTP-ПАТЧ, я скорее делаю PUT на ресурсе.

4. По какой-либо конкретной причине вы избегаете ИСПРАВЛЕНИЯ? Похоже, что это точно соответствует моему варианту использования, который обновляет подмножество всех полей (поскольку другие поля по дизайну не могут обновляться клиентом). Мое понимание PUT заключается в том, что вы должны отправлять совершенно новое состояние для ресурса.

5. Совсем нет. Но я обычно думаю, что элемент является самим ресурсом.

Ответ №2:

Когда-то у меня было аналогичное требование, клиент хотел знать последние обновленные элементы. Для этого я расширил свой ресурс коллекции с помощью параметра «последнее обновление»:

 
GET /items?modifiedAfter=2011-10-10/10:10:10
  

Затем эта измененная информация должна быть прикреплена к item-data где-нибудь в серверной части. Api-клиенты могут сами решать, сколько или как далеко в прошлом они хотят захватить. Как полные, так и дельта-запросы просты в реализации.

Попытка работать с ИСПРАВЛЕНИЕМ и кэшированием в коллекциях была очень сложной и далеко не тривиальной (работа со стандартными заголовками электронных тегов, отображение «правильных» интересующих элементов и т. Д., жесткая реализация клиента). Основная проблема заключается в том, что коллекции часто имеют очень динамичное и изменяющееся поведение.

В итоге работа с modifiedAfter ресурсами для сбора данных как на стороне сервера, так и на стороне api-клиента была довольна.

Помимо вопроса о кэшировании, оцените, действительно ли вам нужны частичные обновления. В большинстве случаев я предпочитаю более простое полное обновление (с использованием PUT ).

Комментарии:

1. Почему бы не использовать заголовки If-Modified-Since и Last-Modified? Соглашение IMO о конфигурации лучше