Подкачка страниц в наборе отдыха

Прочитайте это . Плюсы и минусы интерпретируемых языков.

. Эта идея относится к вашей проблеме.

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

130
задан Joseph Holsten 4 September 2009 в 22:18
поделиться

8 ответов

Мне кажется, что расширения диапазона HTTP не предназначены для вашего случая использования, и поэтому вам не следует пытаться. Частичный ответ подразумевает 206 , и 206 должны быть отправлены только в том случае, если клиент попросил об этом.

Вы можете рассмотреть другой подход, например, тот, который используется в Atom (где представление может быть частичным и возвращается со статусом 200 и, возможно, ссылками на страницы). См. RFC 4287 и RFC 5005 .

23
ответ дан 24 November 2019 в 00:26
поделиться

Если существует более одной страницы ответов, и вы не хотите предлагать сразу всю коллекцию, означает ли это, что есть есть несколько вариантов?

В запросе к / db / questions верните 300 вариантов выбора с заголовками Link , которые указывают, как перейти на каждую страницу как а также объект JSON или HTML-страницу со списком URL-адресов.

Link: <>; rel="http://paged.collection.example/relation/paged"
Link: <>; rel="http://paged.collection.example/relation/paged"
...

У вас будет один заголовок Link для каждой страницы результатов (пустая строка означает текущий URL-адрес, а URL-адрес тот же для каждой страницы, только доступ с разных диапазонов), и отношение определяется как настраиваемое в соответствии со спецификацией Link . Эта связь объясняет ваш обычай 266 или ваше нарушение 206 . Эти заголовки являются вашей машиночитаемой версией, поскольку все ваши примеры в любом случае требуют понимающего клиента.

(Если вы придерживаетесь маршрута «диапазон», я считаю, что ваш собственный код возврата 2xx , как и вы описал это, было бы здесь наилучшим поведением. Ожидается, что вы сделаете это для своих приложений и подобных [«Коды состояния HTTP являются расширяемыми.»], и у вас есть веские причины.)

300 Multiple Choices говорит вам СЛЕДУЕТ также предоставить тело с возможностью выбора пользовательским агентом. Если ваш клиент понимает, он должен использовать заголовки Link . Если это пользователь, просматривающий вручную, возможно, HTML-страница со ссылками на специальный «страничный» корневой ресурс, который может обрабатывать отображение этой конкретной страницы на основе URL-адреса? / humanpage / 1 / db / questions или что-то подобное?


Комментарии к сообщению Ричарда Левассера напоминают мне о дополнительной опции: заголовок Accept (раздел 14.1). Когда появилась спецификация oEmbed, я задался вопросом, почему это не было сделано полностью с использованием HTTP, и написал альтернативу, использующую их.

Сохраните 300 множественных вариантов выбора , ссылку и HTML-страница для начального наивного HTTP GET , но вместо использования диапазонов, ваша новая взаимосвязь подкачки должна определять использование заголовка Accept . Ваш последующий HTTP-запрос может выглядеть следующим образом:

GET /db/questions HTTP/1.1
Host: paged.collection.example
Accept: application/json;PagingSpec=1.0;page=1

Заголовок Accept позволяет вам определить приемлемый тип контента (ваш возврат JSON), а также расширяемые параметры для этого типа (номер вашей страницы). Риффинг в моих заметках из моей записи oEmbed (не могу ссылаться на это здесь, я перечислю это в моем профиле), вы могли бы быть очень точным и предоставить версию спецификации / отношения здесь на случай, если вам нужно переопределить то, что страница означает в будущем.

5
ответ дан 24 November 2019 в 00:26
поделиться

Редактировать:

Поразмыслив еще немного, я склонен согласиться с тем, что заголовки Range не подходят для разбивки на страницы. По логике, заголовок Range предназначен для ответа сервера, а не приложений. Если вы обслужили 100 мегабайт результатов, но сервер (или клиент) мог обрабатывать только 1 мегабайт за раз, то для этого и предназначен заголовок Range.

Я также считаю, что подмножество ресурсов является свой собственный ресурс (похожий на реляционную алгебру.), поэтому он заслуживает представления в URL.

В общем, я отказываюсь от своего первоначального ответа (ниже) об использовании заголовка.


Я думаю, вы ответили на свой вопрос, подробнее или меньше - вернуть 200 или 206 с диапазоном содержимого и при необходимости использовать параметр запроса. Я бы обнюхал пользовательский агент и тип контента и, в зависимости от них, проверьте параметр запроса. В противном случае потребуйте заголовки диапазона.

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

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

Конечно, также ведутся споры о том, должен ли URL содержать все необходимое состояние для такого рода вещей. Указание диапазона с использованием заголовков может быть сочтено некоторыми «неудовлетворительным».

Кроме того, было бы неплохо, если бы серверы могли отвечать заголовком «Can-Specify: Header1, header2»,

4
ответ дан 24 November 2019 в 00:26
поделиться

Вы можете подумать об использовании модели наподобие протокола Atom Feed, поскольку он имеет разумную HTTP-модель коллекций и способы управления ими (где безумие означает WebDAV).

Существует Протокол публикации Atom , который определяет модель сбора и операции REST, плюс вы можете использовать RFC 5005 - Пейджинг и архивирование каналов для постраничного просмотра больших коллекций.

Переключение с Содержание Atom XML в JSON не должно влиять на идею.

3
ответ дан 24 November 2019 в 00:26
поделиться

Вы можете обнаружить заголовок Range и имитировать Dojo, если он присутствует, и имитировать Atom, если нет. Мне кажется, это аккуратно разделяет варианты использования. Если вы отвечаете на запрос REST из своего приложения, вы ожидаете, что он будет отформатирован с заголовком Range . Если вы отвечаете обычному браузеру, то, если вы вернете ссылки для разбиения на страницы, это позволит инструменту предоставить простой способ изучить коллекцию.

1
ответ дан 24 November 2019 в 00:26
поделиться

Я думаю, что настоящая проблема здесь в том, что в спецификации нет ничего, что говорило бы нам, как делать автоматические перенаправления при столкновении с 413 - Requested Entity Too Large.

Я боролся с этим та же проблема недавно, и я искал вдохновения в книге RESTful Web Services . Лично я не думаю, что 206 подходит из-за требований к заголовку. Мои мысли также привели меня к 300, но я подумал, что это больше для разных типов пантомимы, поэтому я посмотрел, что Ричардсон и Руби сказали по этому поводу в Приложении B, стр. 377. Они предполагают, что сервер просто выбирает предпочтительный вариант. представление и отправить его обратно с 200, в основном игнорируя представление о том, что это должно быть 300.

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

Позже я начал думать, что, может быть, лучше всего отправить 307-временное перенаправление на ссылка, которая будет выглядеть примерно как / db / questions / 1,25 - которая оставляет исходный URI в качестве канонического имени ресурса, но ведет к подчиненному ресурсу с соответствующим именем. Это поведение, которое я хотел бы видеть из 413, но 307 кажется хорошим компромиссом. На самом деле еще не пробовал это в коде. Еще лучше, если перенаправление будет перенаправлять на URL-адрес, содержащий фактические идентификаторы последних заданных вопросов. Например, если у каждого вопроса есть целочисленный идентификатор, и в системе 100 вопросов, и вы хотите показать десять самых последних, запросы к / db / questions должны быть 307 ' d к / db / questions / 100,91

Это очень хороший вопрос, спасибо, что задали его. Вы подтвердили мне, что я не сумасшедший, потому что целыми днями думал об этом.

3
ответ дан 24 November 2019 в 00:26
поделиться

Мне кажется, что лучший способ сделать это - включить диапазон в качестве параметров запроса. например, GET / db / questions /? date> mindate & date . После GET в / db / questions / без параметров запроса, вернуть 303 с Расположение: / db / questions /? параметры-запроса-для-получения-страницы-по-умолчанию . Затем укажите другой URL-адрес, по которому кто-либо использует ваш API для получения статистики о коллекции (например, какие параметры запроса использовать, если ему нужна вся коллекция);

0
ответ дан 24 November 2019 в 00:26
поделиться

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

Клиент ДОЛЖЕН включать заголовок «Диапазон», чтобы указать, какая часть коллекции ему нужна, или иным образом быть готовым обработать ошибку 413 REQUESTED ENTITY TOO LARGE, когда ошибка запрошенная коллекция слишком велика для получения за один цикл приема-передачи.

Сервер отправляет ответ 206 PARTIAL CONTENT с заголовком Content-Range, указывающим, какая часть ресурса была отправлена, и заголовком ETag для определения текущей версия коллекции. Обычно я использую ETag, похожий на Facebook {last_modification_timestamp} - {resource_id}, и я считаю, что ETag коллекции - это ETag самого последнего измененного ресурса, который она содержит.

Чтобы запросить определенную часть коллекции, клиент ДОЛЖЕН использовать заголовок «Range» и заполнить «If-Match» заголовок с ETag коллекции, полученной из ранее выполненных запросов на получение других частей той же коллекции. Таким образом, сервер может проверить, что коллекция не изменилась, перед отправкой запрошенной части. Если существует более свежая версия, возвращается ответ 412 PRECONDITION FAILED, чтобы предложить клиенту получить коллекцию с нуля. Это необходимо, потому что это может означать, что некоторые ресурсы могли быть добавлены или удалены до или после запрашиваемой в данный момент части.

Я использую ETag / If-Match в тандеме с Last-Modified / If-Unmodified-Since для оптимизации кеширования. Браузеры и прокси-серверы могут полагаться на один или оба из них в своих алгоритмах кэширования.

Я думаю, что URL-адрес должен быть чистым, если он не включает запрос поиска / фильтрации. Если задуматься, поиск - это не что иное, как частичное представление коллекции. Вместо URL-адресов типа cars / search? Q = BMW мы должны увидеть больше автомобилей? Manufacturer = BMW.

34
ответ дан 24 November 2019 в 00:26
поделиться
Другие вопросы по тегам:

Похожие вопросы: