В архитектуре REST вы в первую очередь сосредотачиваетесь на том, чтобы отделять клиентов от соответствующих API, чтобы позволить серверной стороне развиваться свободно, не нарушая клиентов.Такие свойства особенно удобны, если ваш API запрашивается множеством клиентов, не находящихся под вашим контролем.В то время как простым пользовательским решениям, у которых только внешний интерфейс или мобильный пользовательский интерфейс взаимодействуют с бэк-API, такая архитектура на самом деле не нужна, никто не остановит вас, если вы все еще будете настаивать на ее реализации.Но истина здесь в том, что вы не выиграете от архитектуры REST, если не будете придерживаться строгих и строгих ограничений.Это также включает в себя любые клиенты.Если только один клиент не соблюдает эти рекомендации, у него будет шанс на проблемы с совместимостью.
По своей сути REST - это просто обобщение модели взаимодействия, используемой в Интернете, которая позволяет ему масштабироваться до своего размера.это сегодня.Основная предпосылка модели взаимодействия должна заключаться в том, что сервер / API обучает клиента тому, что он может делать дальше и как этого добиться.Если вы посмотрите на большинство веб-взаимодействий, вы увидите, что сервер предоставляет ссылки и формы, с которыми пользователь может взаимодействовать.После нажатия на ссылку клиент загружает содержимое этой ссылки и представляет его клиенту.Форма позволяет клиенту предоставлять информацию, которая понадобится серверу для выполнения определенных задач от имени клиента.Таким образом, клиент не нуждается во внеполосной информации, такой как соответствующая документация или руководство.Через доступность определенных элементов должно быть ясно, как кто-то должен взаимодействовать с такого рода элементом.Т.е. если вы визуализируете таблицу данных, в которой вы можете редактировать или удалять определенные элементы, такая таблица обычно содержит изображение корзины или карандаша.При нажатии на карандаш отображается форма, содержащая доступные данные, которые можно использовать для изменения определенных элементов этой записи, а при нажатии на значок корзины для мусора запись таблицы удаляется (возможно, после проверки безопасности).Весь этот поток взаимодействия можно обобщить как HATEOAS - Гипертекст как движок состояния приложения.
Основной совет о том, как добиться чего-то с помощью REST, - смоделировать задачу под рукой, как если бы вы взаимодействовали с сетью.стр.Итак, как можно сделать что-то вроде сортировки через REST?Либо сервер уже предоставляет клиенту информацию, либо он позволяет модифицировать ресурс (collection-) в соответствии с требованиями.Первый метод просто предоставляется через ссылки, которые в дальнейшем могут быть сделаны доступными через значки, которые сообщают цель возможности взаимодействия.В таблице это может быть индикатор, который вы можете сортировать по определенному имени столбца или тому подобное.Другая возможность состоит в том, что сервер учит клиента тому, что он может делать дальше.Здесь сервер может разрешить переупорядочивать записи локально, перетаскивая или щелкая записи на их новую позицию, а затем передавая желаемый результат на сервер или позволяя клиенту загрузить определенный сценарий на сервер, который выполняет это действие.
Поскольку REST ориентирован на приложения, а не на людей, доступность определенных значков может не использоваться приложениями напрямую.Вместо значков доступность указывается через имена отношений ссылок, которые должны быть либо стандартизированными , основанными на расширениях с использованием абсолютных URI, либо использовать общие онтологии, такие как dublin-core или другие микроформаты .Некоторые медиа-типы могут также дать подсказку, на какие ссылочные отношения может рассчитывать клиент и в каком контексте используются эти ссылочные отношения.
Возвращаясь к актуальному вопросу о том, как изменить порядок элементов в REST-архитектуре.В зависимости от размера коллекции доступно несколько подходов.Как и в Интернете, где небольшая таблица может предоставлять элемент управления редактирования для одновременного обновления всей таблицы, то же самое можно сделать и в архитектуре REST.Здесь может быть предоставлена ссылка с отношением ссылки edit
, чтобы сообщить клиенту, что, если он хочет отредактировать всю коллекцию, он должен посетить URI, сопровождающий имя отношения ссылки.После отслеживания этого URI он может получить медиа-тип, представляющий форму, аналогичную HTML-формам, которая позволяет отправлять обновленное представление этой коллекции на ресурс коллекции сразу, используя запрос HTTP PUT
.
Если в этой коллекции много записей или может быть несколько страниц записей, другой подход, вероятно, будет более выгодным.Одна из них может заключаться в том, что клиент собирает все (или достаточные) из доступных записей или страниц и рассчитывает изменения, которые необходимо внести в этот ресурс, чтобы преобразовать текущий порядок в желаемый.Это идеальное совпадение для операции HTTP PATCH
.С помощью application/json-patch+json
вы можете буквально перемещать десятки записей одновременно.Из-за того, что запрос должен быть применен атомарно, применяются все изменения или нет.
Хотя вы можете отправлять сценарий, который должен выполняться сервером также через HTTP POST
запрос, так как здесь сценарий выполняется в соответствии с собственной семантикой сервера, это, помимо опасности, недух философии REST как сервера не инструктирует клиента о том, что делать дальше, и клиент должен иметь некоторые знания о внутренней структуре сервера.
Как ответы Clay
иzardilior
оба предлагают определенную структуру URI для перемещения определенных записей, я категорически против такой вещи.Во-первых, URI в целом является указателем на ресурс.Это де-факто ключ кеша, если вы запрашиваете запись через GET
, и любой небезопасный запрос на этот URI удалит кэшированное значение.Филдинг сделал кэширование требования в архитектуре REST , а не вариант.Кроме того, клиент не должен интерпретировать URI, поскольку они не передают значение.Это то, для чего существуют связи.Как упоминалось в главе 6.2 идентификаторов тезисов Филдинга, для которых используется URI, они должны изменяться как можно реже.
... Определение ресурса в REST основано наПростая предпосылка: идентификаторы должны меняться как можно реже .Поскольку в Интернете используются встроенные идентификаторы, а не серверы ссылок, авторам необходим идентификатор, который точно соответствует семантике, которую они намереваются в гипермедиа-ссылке, позволяющей ссылке оставаться статической, даже если результат доступа к этой ссылке может изменяться со временем .REST выполняет это, определяя ресурс как семантику того, что автор намеревается идентифицировать, а не значение, соответствующее этой семантике во время создания ссылки.Затем он оставляется на усмотрение автора, чтобы убедиться, что идентификатор, выбранный для ссылки, действительно определяет предполагаемую семантику....
... ресурс может иметь много идентификаторов.Другими словами, могут существовать два или более разных URI, которые имеют эквивалентную семантику при использовании для доступа к серверу.Также возможно иметь два URI, которые приводят к тому, что один и тот же механизм используется при доступе к серверу, и все же эти URI идентифицируют два разных ресурса, потому что они не означают одно и то же.
Семантика является-продукт действия по присвоению идентификаторов ресурсов и заполнению этих ресурсов представлениями.Серверное или клиентское программное обеспечение ни в коем случае не должно знать или понимать значение URI....
Используя URI, такой как /user/1/after/2
или /user/1/reorder/2
, вы не только выбираете целевой ресурс, но и отправляете запросы на каждое изменение позиции записи, кроме того, что клиент должен знать семантику этого URI.генерировать один.Как объяснено выше, сервер должен учить клиента тому, как добиться чего-либо.Тем самым он должен предоставить клиентам все возможные варианты.В таком случае, если у вас есть коллекция с 10.000 записей, вам нужно будет предоставить либо 2 ссылки на запись для поэтапного перемещения записи, либо 9999 ссылок на запись, чтобы переместить элемент в целевую позицию.В частности, в последнем случае получен огромный ответ.
Еще одна причина, по которой я против предлагаемых решений, заключается в том, что при переупорядочении записей в коллекции URI, а также фактических данных соответствующихна сами записи вообще не следует влиять, если только вы не сделаете номер позиции частью URI, что я не рекомендую, так как изменение URI будет означать, что целевой ресурс теперь является целевым, даже если фактическая вещь, представленная этим ресурсом, остаетсятот же самый.Таким образом, URI должен оставаться стабильным.
Я также утверждаю, что позиция записи в самой коллекции не относится к точным данным этой записи и поэтому является просто метаданными, прикрепленными к записи.Таким образом, это может быть допустимое свойство самого ресурса коллекции, которое вы можете использовать для дальнейшей фильтрации записей, но такие данные не должны быть частью соответствующей записи.Если вы настаиваете на включении таких метаданных в данные или ключ записи, вам может потребоваться изменить по крайней мере 2 записи за ход, чтобы обновить индексы позиций затронутых записей.В худшем случае вы должны обновить каждый индекс позиции.По моему мнению, это само по себе является достаточной причиной, чтобы не включать такие изменчивые данные в саму запись.
В отношении представления записей в правильном порядке должен быть выбран соответствующий тип носителя, который определяет, как получатель долженобработать полезную нагрузку, полученную в этом формате представления.Этот тип носителя должен поддерживаться всеми сторонами, иначе он не сможет правильно обрабатывать полезную нагрузку.Типы носителей, такие как application/vnd.collection+json
, существуют, хотя базовый тип JSON не гарантирует правильность порядка.Здесь вам, вероятно, понадобится пользовательский медиа-тип, который включает в себя позицию в качестве информации о поле, которая должна соблюдаться клиентом.Вы можете взять существующий тип носителя и уточнить его семантику, расширив его и добавив в него новые определения.Это означает, что вы можете определить, что определенное поле указывает положение этой записи в списке, и клиенты должны соблюдать порядок при представлении записей пользователю.Определенные переопределения могут быть возможны даже с profiles
.Т.е. вышеупомянутый collection+json
тип носителя поддерживает профили, которые позволяют вам сказать клиенту, какой тип записи.Тип носителя, такой как application/vnd.collection+json;profile=http://example.org/profiles/order http://schema.org/Order
, указывает, что коллекция содержит заказы, соответствующие схемам schema.org.Другие форматы представления, такие как XML или простой текст, могут не иметь такой проблемы с порядком записей, хотя могут повлиять на другие области.
Чтобы подвести итог этой публикации, пусть серверы обучат клиентов тому, что они должны знать, и предоставят имссылки и данные, с которыми они могут работать.Проектируйте поток взаимодействия так, как если бы вы проектировали конечный автомат, подобный тому, который описан Asbjørn Ulsberg или Jim Webber .Благодаря наличию связей между ссылками вы отделяете URI от их семантического предназначения, что не заставляет клиентов анализировать и интерпретировать URI.Что касается фактического упорядочения записей, нужно немного позаботиться о формате представления, поскольку не все форматы соблюдают порядок упорядочения естественным образом, как в случае с JSON.