REST - это аббревиатура для передачи текущего состояния ресурса в формате представления, поддерживаемом клиентом. Поскольку REST является обобщением Всемирной паутины, те же понятия, которые вы используете для Интернета, также применимы к приложениям, следующим модели архитектуры REST. Таким образом, основной вопрос решается вокруг: Как бы вы спроектировали свою систему для работы на веб-страницах и применили те же шаги к вашему дизайну.
Как Кассио уже упоминал, что написание URI не имеет значения для клиентов, так как URI остается URI, и вы не можете определить из URI, является ли система «RESTful» или нет. На самом деле, нет такой вещи, как «RESTful» или «RESTless» URI, поскольку URI, как указано выше, остается URI. Вероятно, лучше рассматривать URI как ключ, используемый для кэширования ответов в локальном или промежуточном кэше. Филдинг сделал поддержку кеширования даже с ограничением , а не просто с опцией.
Поскольку REST - это не протокол, а просто архитектурный стиль, вы в принципе не обязаны применять его строго, хотя вы, безусловно, упустите обещанные преимущества, такие как отделение клиентов от API, свобода развития на стороне сервера, не ломая клиентов и делая клиентов в целом более устойчивыми к изменениям. Филдинг даже заявил, что приложения, которые нарушают ограничения, накладываемые им на REST, вообще не следует называть REST , чтобы избежать путаницы.
Я не согласен с user991710 в одном из его комментариев о том, что REST нельзя использовать для представления процессов, однако я согласен с тем, что REST также не должен пытаться создавать новые глаголы. Как упоминалось ранее, REST предназначен для передачи текущего состояния ресурсов в поддерживаемом формате представления. Если задача может быть представлена в виде потока данных, то она также может быть представлена клиенту. Самоинформативность сообщений, т. Е. Использование типа носителя, который определяет правила обработки полезных данных, гарантирует, что клиент сможет разобраться в данных. То есть Ваш браузер может отображать изображения, воспроизводить видео, показывать текст и тому подобное, поскольку он знает, как интерпретировать поток данных соответствующим образом. Поддержка таких полей может быть добавлена с помощью специальных дополнений или плагинов, которые могут загружаться динамически во время выполнения даже без перезапуска приложения.
Если бы мне приходилось разрабатывать задачи для веб-страниц, я бы изначально возвращал отображаемое по страницам представление существующих задач, возможно, отображаемых в таблице, со ссылкой на страницу, которая может создавать новые задачи, или ссылкой в каждой строке. обновить или удалить существующую задачу. Страницы create-new и update могут использовать одну и ту же HTML-форму для ввода или обновления информации о задачах. Если задача должна быть назначена в качестве подзадачи для другой задачи, вы можете выбрать родительскую задачу из заданного набора задач, например, в раскрывающемся текстовом поле, или ввести URI родительского элемента в поле. выделенное поле. При отправке задачи будет использоваться HTTP-метод POST
, который будет выполнять операцию на основе собственной семантики сервера, поэтому создается новый ресурс или обновляется один или несколько из них на сервере. Суть в том, что все, что может сделать клиент, преподается сервером. Форма для добавления новых или обновления существующих задач просто сообщает клиенту, какие поля поддерживаются (или ожидаются) сервером. На самом деле для выполнения запроса клиенту не требуется никаких внешних внеполосных знаний. На сервере все еще есть возможность отклонять неполные полезные нагрузки или полезные нагрузки, которые нарушают определенные ограничения, и клиент узнает об этом, получив соответствующее сообщение об ошибке.
Поскольку клиенты не должны анализировать или интерпретировать URI, они будут использовать определенный текст, описывающий, что делают URI. В браузере изображение мусорной корзины может использоваться в качестве символа для удаления, в то время как карандаш может использоваться в качестве символа для обновления существующей записи (или тому подобного). Как люди, мы быстро понимаем, для чего предназначены эти ссылки, без необходимости читать символы фактического URI.
Последние два абзаца просто суммировали, как может выглядеть модель взаимодействия на обычной веб-странице. Те же понятия должны быть использованы и в архитектуре REST. Контент, которым вы обмениваетесь, может отличаться в большей степени, в идеале с стандартизированными форматами представления , по сравнению со старшим братом, Интернетом, хотя концепции ссылок используются для ссылки с одного ресурса на другие ресурсы, и сервер учит клиентов тому, что это необходимо применить здесь. Однако по сравнению с HTML вы можете использовать больше HTTP-методов, чем просто POST
и GET
. Удаление представления ресурса, вероятно, более целесообразно при использовании метода DELETE
, чем при использовании метода POST
. Кроме того, для обновлений может иметь смысл PUT
или PATCH
, в зависимости от ситуации. В отличие от использования разумных картинок для намека пользователей на то, для чего может пригодиться эта ссылка, следует использовать имена отношений ссылок, которые намекают клиентам о назначении ссылки. Такие имена связей должны быть стандартизированными или, по крайней мере, выражать здравый смысл, такой как выраженный через специальные онтологии , или использовать абсолютные URI в качестве механизма расширения .
Вы можете добавить выделенные ссылки, чтобы показать коллекцию всех задач на основе определенных фильтров, то есть всех задач или только родительских задач, а что нет, чтобы клиент мог выполнять итерацию по интересующей его задаче. При выборе задачи вы можете добавьте ссылки на все подзадачи, которые может вызвать клиент, чтобы узнать, что это за подзадачи, если это необходимо. Здесь URI задач могут оставаться неизменными, что поддерживает кэширование по умолчанию. Обратите внимание, что я ничего не упомянул относительно того, как вы должны хранить данные в своем бэкэнде, так как это всего лишь некоторые детали реализации, которые обычно не интересуют клиента. Это просто идеальный случай, когда доменная модель не обязательно должна быть похожим на представление состояния ресурсов.
Относительно того, какая операция HTTP для выполнения повышения или понижения задачи является в основном неким выбором дизайна, который также может зависеть от формата представления, на который обмениваются полезные данные. Поскольку HTTP поддерживает только POST
и GET
, такое изменение может быть запрошено через POST
, другие типы носителей могут поддерживать другие HTTP-методы , такие как PUT
, которые, согласно его * Спецификация 1044 * (последний абзац, стр. 27) может иметь побочные эффекты, или PATCH
, который необходимо применять атомарно - либо полностью, либо вообще не применять. PATCH
на самом деле похоже на исправление программного обеспечения, где набор инструкций должен быть применен к некоторому целевому коду. Уильям Дюран резюмировал эту концепцию в довольно цитируемом блоге . Однако позже он обновил свой пост в блоге, отметив, что с помощью application/merge-patch+json
можно использовать более естественный и интуитивно понятный способ «обновления» ресурсов. Что касается поддержки формы, существует пара проектов, таких как hal-формы , halo-json (halform) , Ion или hydra , которые предлагают такое определение, но в настоящее время не имеют более широкой библиотечной поддержки или окончательного стандарта. Так что немного работы еще предстоит внести в принятый стандарт.
Чтобы завершить этот пост, вы должны разработать свой API так, как будто бы вы разрабатывали свою систему для работы с веб-страницами, применять те же концепции, которые вы используете для взаимодействия с типичными веб-страницами, такими как ссылки и формы, и использовать их в ваши ответы. Какая операция HTTP вы выполняете с помощью фактического продвижения или понижения, может зависеть от фактического типа носителя и от того, какие операции HTTP он поддерживает. POST
должен работать во всех случаях, PUT
, вероятно, более интуитивно понятен для типичных обновлений, выполняемых в веб-формах, в то время как для исправления потребуется, чтобы ваш клиент фактически рассчитал шаги, необходимые для преобразования представления текущего ресурса в желаемое (если вы используете application/json-patch+json
в частности). application/merge-patch+json
также может быть применимо, что значительно упростит исправление, поскольку текущие данные, содержащиеся в форме, могут быть просто отправлены на сервер, а правила по умолчанию будут определять, было ли удалено, добавлено или обновлено поле.