Давайте сначала обсудим упомянутые вами варианты:
- 1:
DELETE
не обязательно удалять или удалять состояние, содержащееся в ресурсе, на который нацелен URI. Это просто требует, чтобы сопоставление целевого URI с ресурсом было удалено, а это означает, что последовательный запрос по тому же URI не должен возвращать состояние ресурса в дальнейшем, если в это время над этим URI не выполнялась никакая другая операция. Поскольку вы хотите повторно использовать URI, указывающий на ресурс настроек клиента, это, вероятно, неправильный подход.
- 2: REST не заботится о написании URI, если оно соответствует RFC3986 а>. Не существует такой вещи, как RESTful или RESTless URI. URI в целом является указателем на ресурс, и клиент должен воздерживаться от извлечения сведений о нем путем его разбора и интерпретации. Однако клиент и сервер должны использовать имена связей ссылок, к которым присоединены URI. Таким образом, URI можно изменить в любое время, и клиент останется в состоянии взаимодействовать со службой дальше. Однако представленный URI оставляет запах RPC, о котором автоматический клиент совершенно не подозревает.
- 3:
PATCH
на самом деле очень похоже на исправление, выполняемое инструментами управления версиями кода. Здесь клиент должен предварительно рассчитать шаги, необходимые для преобразования исходного документа в его желаемую форму, и содержать эти инструкции в так называемом патч-документе. Если этот документ с исправлениями применяется кем-то, а состояние документа совпадает с версией, используемой документом с исправлениями, изменения должны быть применены правильно. Во всех остальных случаях исход не ясен. Хотя application/json-patch+json очень похож на философию документа исправления, содержащего отдельные инструкции, application/merge-patch+json имеет несколько иной подход, определяя значение по умолчанию правила (обнуление свойства приведет к удалению, включение свойства приведет к его добавлению или обновлению, а отсутствие свойств приведет к игнорированию этих свойств в исходном документе)
- 4: В этом смысле сначала получить последнее состояние из ресурса и локально обновить его/вычислить изменения, а затем отправить результат на сервер, вероятно, лучший подход из перечисленных. Здесь вы должны использовать условные запросы, чтобы гарантировать, что изменения применяются только к той версии, которую вы недавно загруженных и предотвращать проблемы, исключая любые промежуточные изменения, внесенные в этот ресурс.
По сути, в архитектуре REST сервер предлагает клиенту множество вариантов, который в зависимости от его задачи выбирает один из вариантов и выдает запрос на прикрепленный URI. Обычно сервер обучает клиента всему, что ему нужно знать, через представления форм, такие как Формы HTML, формы HAL или ION.
В такой среде settings
, как вы упомянули, является действительным ресурсом сам по себе, а также ресурсом настроек по умолчанию. Таким образом, чтобы позволить клиенту сбросить свои настройки, достаточно просто скопировать содержимое ресурса настроек по умолчанию в целевой ресурс настроек. Если вы хотите быть совместимым с WebDAV, который является просто расширением HTTP, вы можете использовать Операция COPY HTTP (также см. другие зарегистрированные операции HTTP в IANA) а>). Однако для простых HTTP-клиентов вам может понадобиться другой подход, чтобы любые произвольные HTTP-клиенты могли сбросить настройки до желаемого значения по умолчанию.
Как сервер хочет, чтобы клиент выполнял этот запрос, можно узнать с помощью вышеупомянутой поддержки форм. Очень упрощенный подход в Интернете состоял бы в том, чтобы отправить клиенту HTML-страницу с настройками, предварительно заполненными в HTML-форме, возможно, также позволить пользователю заранее настроить свои настройки в соответствии с его пожеланиями, а затем нажать кнопку отправки, чтобы отправить запрос к URI, представленному в атрибуте действия формы, который может быть любым URI, который хочет сервер. Поскольку HTML поддерживает только POST
и GET
в формах, в Интернете вы ограничены POST
.
Можно подумать, что достаточно просто отправить полезную нагрузку, содержащую URI ресурса настроек для сброса и, возможно, URI настроек по умолчанию, на выделенную конечную точку через POST
, а затем позволить ему выполнить свою магию, чтобы сбросить состояние до значения по умолчанию. Однако этот подход обходит кеши и может заставить их поверить, что старое состояние все еще действительно. Кэширование в HTTP работает таким образом, что де-факто URI ресурса используется в качестве ключа, и любые небезопасные операции, выполняемые с этим URI, приведут к вытеснению этого сохраненного контента, так что вместо этого любые последовательные запросы будут напрямую направляться на сервер. вместо этого обслуживается кешем. Когда вы отправляете небезопасный POST
request на выделенный ресурс (или конечную точку с точки зрения RPC), вы упускаете возможность сообщить кэшу об изменении фактического ресурса настроек.
Поскольку REST — это просто обобщение модели взаимодействия, используемой в человеческой сети, неудивительно, что те же самые концепции, используемые в Интернете, применимы и к уровню домена приложения. Хотя здесь также можно использовать HTML, форматы на основе JSON, такие как application /hal+json или вышеупомянутые форматы HAL forms
или ION
, вероятно, более популярны. В целом, чем больше типов мультимедиа может поддерживать ваш сервис, тем больше вероятность того, что сервер будет обслуживать множество клиентов.
В отличие от человеческого Интернета, где изображения, кнопки и прочее предоставляют доступность соответствующего контроля пользователю, произвольные клиенты, особенно автоматизированные, обычно плохо справляются с такими возможностями. Таким образом, должны быть предоставлены другие способы намекнуть клиенту о назначении URI или элемента управления, такие как имена отношений ссылок. В то время как <<
, <
, >
, >>
могут использоваться в ссылке HTML-страницы для обозначения первого, предыдущего, следующего и последнего элементов в коллекции, отношение ссылки здесь предоставляет first
, prev
, next
и last
в качестве альтернативы. Такие отношения ссылок должны быть либо зарегистрированы в IANA, либо по крайней мере следуйте подходу расширения веб-ссылок. Клиент, ищущий URI в отношении prev
, будет знать цель URI, а также сможет взаимодействовать с сервером, если URI когда-либо изменится. По сути, это также то, что представляет собой HATEOAS, используя заданные элементы управления для навигации по приложению через конечный автомат, предлагаемый сервером.
Вот некоторые общие практические правила разработки приложений для архитектур REST:
- Спроектируйте взаимодействие так, как если бы вы взаимодействовали с веб-страницей в Интернете, или, более формально, как с конечным автоматом или протокол приложения домена, как назвал его Джим Уэббер, клиент может работать через
- Позвольте серверам обучать клиентов тому, как должны выглядеть запросы, благодаря поддержке различных типов форм.
- API не должны использовать типизированные ресурсы, но вместо этого полагайтесь на согласование типа контента
- Чем больше типов мультимедиа поддерживает ваш API или клиент, тем выше вероятность взаимодействия с другими узлами.
Короче говоря, очень простой подход заключается в том, чтобы предложить клиенту предварительно заполненную форму со всеми данными, которые составляют настройки по умолчанию. Целевой URI свойства действия нацелен на фактический ресурс и, таким образом, также информирует кэши об изменении. Этот подход также ориентирован на будущее, так как клиенты будут автоматически обслуживаться с новой структурой и свойствами, которые поддерживает ресурс.
... так что аудитория и, следовательно, потенциальные типы клиентов, с которыми я могу столкнуться, довольно малы — разработчики, которые используют мой продукт, развернутый в их частном центре обработки данных или на машинах AWS EC2, и им нужно написать скрипт на любом языке для автоматизации какую-то задачу, а не делать это через пользовательский интерфейс.
REST в смысле архитектурного стиля Филдинга сияет, когда существует множество различных клиентов, взаимодействующих с вашим приложением, и когда необходима поддержка будущей эволюции, неотъемлемо интегрированная в дизайн. REST просто дает вам возможность добавлять новые функции в будущем, а клиенты REST с хорошим поведением просто подберут их и продолжат работу. Если вы взаимодействуете только с очень ограниченным набором клиентов, особенно под вашим контролем, или если вероятность будущих изменений очень мала, REST может быть излишним и не оправдывать дополнительные накладные расходы, вызванные тщательным проектированием и реализацией.
... некоторые технические соображения, такие как кэширование, имеют значение. Соображения человека-пользователя, такие как согласованность дизайна API для различных ресурсов и простота его изучения, также имеют значение. Но может ли какой-нибудь сторонний сканер определить следующие действия, которые он может выполнить из заданного состояния, не так важно...
Термин API design
уже указывает на то, что желателен подход, более похожий на RPC, когда определенные операции доступны пользователю, которые могут вызываться для выполнения некоторых задач. Это все нормально, если вы не называете это REST API из Точка зрения Филдинга. Простая истина здесь заключается в том, что практически нет приложений/систем, которые действительно следуют архитектурному стилю REST, но есть множество плохих примеров, которые неправильно используют термин REST и, следовательно, дают неправильное представление об архитектуре REST, ее цели, а также его преимущества и недостатки. В некоторой степени это проблема, вызванная тем, что люди не читают диссертацию Филдинга (внимательно), а частично из-за общего предпочтения прагматизма и использования / реализации ярлыков для выполнения работы как можно скорее.
Что касается прагматичного взгляда на REST, трудно дать точный ответ, поскольку все, похоже, понимают в нем разные вещи. Большинство этих API в любом случае полагаются на внешнюю документацию, такую как Swagger, OpenAPI и тому подобное, и здесь URI, похоже, является тем, что дает разработчикам представление о цели. Таким образом, URI, оканчивающийся на .../settings/reset
, должен быть понятен большинству разработчиков. Независимо от того, имеет ли URI запах RPC или следует ли следовать семантике соответствующих HTTP-операций, то есть частичных PUT
или полезных данных внутри GET
, это ваш выбор дизайна, который вы должны задокументировать.
person
Roman Vottner
schedule
18.02.2021
DELETE
для меня 2. Согласен, что это не REST по книге. Однако я сразу могу понять, что он делает 3. Согласен еще раз; кроме того, это не только неинтуитивно, что, еслиnull
является допустимым значением для одного из параметров? так что если я отправлюoption: null
, что я имею в виду? установить его наnull
или восстановить по умолчанию? 4. Кажется обременительным В конце концов, REST — это не религия; Я бы выбрал то, что легче всего понять; ИМО вариант 2 - person J. Ed   schedule 18.02.2021