ReST с малой задержкой - как мне ответить на GET, пока идет загрузка? - PullRequest
0 голосов
/ 15 ноября 2018

Я проектирую API ReST , который следует базовому шаблону CRUD .

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

Итак, в процессе я собираюсь использовать что-то вроде этого (улучшения приветствуются):

client: GET /some/item
myapi:  200 OK
        last-modified: time-stamp-of-v1
        etag: some-hash-relating-to-v1-of-my-item-in-this-format
        content: json or whatever
         data/for/some/item/v1... 

client: PUT /some/item
        if-match: some-hash-relating-to-v1-of-my-item-in-this-format
        content: json or whatever
         data/for/some/item/v2... 

myapi:  202 ACCEPTED,   
        content: json or whatever
         time-accepted: time-stamp-after-v1-but-before-v2
         your item will be at /some/item
         here is a URI /some/taskid to track progress

пока идет загрузка:

client: GET /some/item
myapi:  200 OK
        some/item ... 
        last-modified: time-stamp-of-v1
        etag: some-hash-relating-to-v1-of-my-item-in-this-format
>>>>    expires: time-stamp-after-v1-but-before-v2 <<<
>>>>    warning: 110 Response is stale    <<<<
        content: json or whatever
         data/for/some/item/v1... 

client: GET /some/task/id
myapi:  200 OK
        content: json or whatever
         time-accepted: time-stamp-after-v1-but-before-v2
         your item will be at /some/item
         status/of/upload/v2... 

после выполнения задания:

client: GET /some/item
myapi:  200 OKAY
        some/item/v2 ... 
        last-modified: time-stamp-of-v2
        etag: some-hash-relating-to-v2-of-my-item-in-this-format
        content: json or whatever
         data/for/some/item/v2... 

client: GET /some/task/id
myapi:  303 SEE OTHER
         look-here: /some/item

Если вы являетесь прокси-сервером и знаете, что ваш контент устарел, вы можете поставить «предупреждение: 110 - ответ устарел» в заголовке. Однако в этом случае данные еще не являются недействительными. Я хотел бы сказать, что могу гарантировать, что это действительно до тех пор, пока я не получу и не передам запрос на загрузку ( time-stamp-after-v1-but-before-v2 или позже, как если бы я был в контакте с сервером загрузки). На момент получения запроса на загрузку он еще не истек. Я просто ожидаю, что это будет. (На самом деле, если запрос не выполняется, он может вообще не обновляться).

Теперь выбор по умолчанию - просто обслуживать старый контент и позволить клиенту догонять самостоятельно. Это имеет высокую задержку. Если возможно, я хотел бы сделать лучше.

Например, если клиент знает, что срок действия документа истекает, он может опрашивать чаще или может попытаться обновить соединение до веб-сокета и получить уведомление об обновлении, как только я его получу (это все равно будет считаться Rest?)

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

Итак, вопрос: как мне ответить на GET, пока идет загрузка новой версии?

В ожидании ответов по принципу использования инфраструктуры обмена сообщениями, такой как AMQP или zeroMQ, вместо этого для низких задержек, я должен отметить, что этот API действует как шлюз / прокси-сервер AMQP для клиентов, не желающих использовать AMQP напрямую. Информация об использовании веб-хуков или веб-сокетов будет по-прежнему интересной.

Некоторая полезная информация:

1 Ответ

0 голосов
/ 27 ноября 2018

Tl; р;

Пока загрузка ожидает отправки:

client: GET /some/item
myapi:  200 OK
        some/item ... 
        last-modified: time-stamp-of-v1
        etag: some-hash-relating-to-v1-of-my-item-in-this-format
        expires: time-stamp-after-v1-but-before-v2
        stale-while-revalidate: 100
        warning: 110 Response is stale
        content: json or whatever
         data/for/some/item/v1... 

На первый взгляд похоже, что использование Предупреждение неверно. Смотри https://tools.ietf.org/html/rfc7234#section-5.5.0

В этом случае сервер действует как прокси-сервер (но не HTTP-прокси). Он не отключен от AMQP и «Прокси НЕ ДОЛЖЕН отправлять устаревшие ответы», если он не отключен. Это раздражает, так как это выглядело как то, что нужно делать здесь.

4.2.4. Обслуживание устаревших ответов

«Устаревший» ответ - это тот, у которого явно истек срок действия информация или разрешено рассчитывать эвристический срок действия, но не свежий по расчетам в разделе 4.2.

Кэш НЕ ДОЛЖЕН генерировать устаревший ответ, если он запрещен явная внутрипротокольная директива (например, «без хранилища» или директива кеша "no-cache", обязательная повторная проверка директива кеш-ответа или применимый s-maxage или «proxy-revalidate» директива кеш-ответа; см. раздел 5.2.2).

> Кэш НЕ ДОЛЖЕН отправлять устаревшие ответы, если он не отключен
(т. е. он не может связаться с исходным сервером или иным образом найти
прямой путь) или это разрешено явно (например,
директива с максимальным устаревшим запросом; см. раздел 5.2.1).

Кэш ДОЛЖЕН генерировать поле заголовка Warning с 110 код предупреждения (см. раздел 5.5.1) в устаревших ответах. Аналогично, кэш ДОЛЖЕН генерировать 112 предупреждений (см. раздел 5.5.3) в устаревшем состоянии. ответы, если кеш отключен.

Кэш НЕ ДОЛЖЕН генерировать новое поле заголовка Warning, когда
пересылка ответа, который не имеет поля заголовка Age, даже если ответ уже устарел. Кэш не должен проверять ответ
это просто стало несвежим в пути.

Также

4,4. Недействительность

Потому что небезопасные методы запроса (Раздел 4.2.1 [RFC7231]), такие как PUT, POST или DELETE могут изменить состояние на
исходный сервер, промежуточные кэши могут использовать их для хранения своего содержимого в курсе.

> Кэш ДОЛЖЕН сделать недействительным действующий URI запроса (раздел 5.5 из
[RFC7230]), а также URI в Location и Content-Location поля заголовка ответа (если есть), когда код состояния без ошибок
получен в ответ на небезопасный метод запроса.

Однако, если используется stale-while-revalidate , требуется предупреждение (см. https://tools.ietf.org/html/rfc5861)

  1. Устаревшее расширение Cache-Control

    При наличии в ответе HTTP устаревший Cache- revalidate Расширение элемента управления указывает, что кэши МОГУТ обслуживать ответ в
    который появляется после того, как становится устаревшим, до указанного числа
    секунд.

    stale-while-revalidate = "stale-while-revalidate" "=" дельта-секунды

    Если кэшированный ответ обслуживается устаревшим из-за наличия этого
    расширение, кэш ДОЛЖЕН попытаться повторно проверить его, пока
    выдача устаревших ответов (т.е. без блокировки).

Мне показалось, что это неясно, поэтому я отправил опечаток . Это было отклонено (хотя на момент написания он все еще показывался как сообщалось) на том основании, что расширения элемента управления кэшем в rfc5861 переопределяют НЕ ДОЛЖНО в rfc7234 («это явно разрешено», см. Выше).

Можно использовать expires , но это не очень полезно, поскольку ничего не значит.

5,3. Истекает

В поле заголовка «Срок действия» указывается дата / время, после которого
ответ считается устаревшим. См. Раздел 4.2 для дальнейшего обсуждения модели свежести.

> Наличие поля Expires не означает, что оригинал
ресурс изменится или перестанет существовать в, до или после этого
времени.

...