Лучшие практики для реализации длительных поисков с помощью REST - PullRequest
27 голосов
/ 11 октября 2011

Как часть службы REST, мне нужно реализовать поисковый вызов.Основная идея состоит в том, что пользователь может ПОСТАВИТЬ новый поиск и ПОЛУЧИТЬ результаты:

POST http://localhost/api/search
GET http://localhost/api/search?id=123

Однако мой поиск может продолжаться несколько минут и возвращать частичные результаты, пока он не будет выполнен.То есть GET-запрос будет возвращать что-то вроде:

status: running
results: a, b, c.

, тогда как следующий GET-запрос может вернуть

status: completed
results: a, b, c, d, e.

Это противоречит семантике запроса RESTful GET.Запрос всегда должен возвращать один и тот же результат при вызове несколько раз.Например, когда пользователь использует прокси-сервер кэширования, полные результаты могут никогда не доставляться пользователю.

Вопрос: Есть ли способ обеспечить действительно RESTful-реализацию для длительных поисков с частичными результатами?

Ответы [ 5 ]

31 голосов
/ 11 октября 2011

Во время поиска вы можете установить соответствующие заголовки ответа (например, Expires или max-age), чтобы указать, что ответ не должен кэшироваться (HTTP / 1.1 14.9.3 , 13.4 ).

Как только результат поиска будет завершен, вы можете отправить более подходящий заголовок Expires / max-age, чтобы разрешить или расширить кешируемость результата.

Клиенту придется перезапускать ресурс до тех пор, пока его состояние поиска не будет завершено.Возможно, клиент мог бы использовать значение заголовка Expires, чтобы определить, когда ему следует повторно запросить обновленные результаты.

Наряду с этим можно также использовать собственный код состояния 2XX для указаниячто результат еще не завершен.Может быть HTTP/1.1 299 In Progress, или что-то еще имеет смысл.В спецификации указано, что коды состояния HTTP являются расширяемыми .

Кстати, ваше утверждение:

Это противоречит семантике запроса RESTful GET.Запрос должен всегда возвращать один и тот же результат при вызове несколько раз.

не верно для запросов GET - ресурсы могут изменяться.То, что запросы GET являются идемпотентными, означает только то, что "... побочные эффекты от N> 0 идентичных запросов такие же, как для одного запроса" . [спецификация]

9 голосов
/ 11 октября 2011

Несколько дней назад я случайно наткнулся на сообщение в блоге на Reddit, которое касается вашей проблемы.Возможно, вы захотите проверить это: RESTy Билла Хиггина long-ops .

Приятного чтения.

2 голосов
/ 11 февраля 2014

Это не проблема, если первый запрос GET возвращает частичные результаты, а второй запрос GET возвращает полные результаты.Это связано с тем, что первый запрос GET не приводит к изменению результата второго запроса: этот запрос вернул бы полные результаты, даже если первый запрос GET не был выполнен.«Идемпотент» не означает идентичные результаты.Это означает, что первый GET не влияет на второй GET.

Будет проблема, если первый запрос GET вернет частичные результаты, а второй GET вернет оставшиеся результаты (первый GET вернет A, B, C; второй GET вернет D, E, F).Здесь первый GET меняет второй результат, поэтому он не RESTful.

0 голосов
/ 12 октября 2011

Не могли бы вы подождать вместо опроса, если вы просто хотите получить полные результаты?

Почему вы не можете предоставить ресурс как часть вашего POST, который получит результаты PUT? Вы предоставляете REST-интерфейс «обратного вызова», поэтому вместо опроса клиентский процесс ожидает PUT для предоставленного ресурса. Затем вы можете либо ПОЛУЧИТЬ результаты, либо результаты могут быть включены в PUT.

0 голосов
/ 11 октября 2011

Возможно, это не самый элегантный ответ, но обойдется кэширование прокси: просто не отправляйте один и тот же запрос дважды. Добавьте метку времени к запросу (&time=1318355458). Таким образом, каждый запрос уникален (вы также можете добавить миллисекунды ко времени, если вы запрашиваете> 1 Гц).

Что касается следования доктрине «Запрос должен всегда возвращать один и тот же результат при вызове несколько раз», то это логически противоречит цели возврата частичных результатов в разное время для одного и того же запроса.

...