Отображение функции без аргументов в REST - PullRequest
0 голосов
/ 24 мая 2019

Давайте представим, что у вас есть ресурс REST Restriction (представьте себе контрольно-пропускной пункт), в котором есть несколько фильтров (например, улица, направление и т. Д.). Ограничение имеет expiry, который является датой и временем. Это учитывается только в логике приложения, когда срок действия истекает в будущем или не установлен / ноль (нет срока действия).

Теперь с процедурным стилем, я мог бы просто иметь метод ограничения, скажем, expire(), который установил бы срок действия текущего времени.

С помощью REST вместо этого мы изменяем состояние ресурсов. Я разрываюсь между этими более или менее функционально эквивалентными определениями API:

PATCH /restrictions/{id}
data = {
  "expiry": 1558654742
}

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

PATCH /restrictions/{id}
data = {
  "expired": true
}

Поле expired - это временное виртуальное свойство, которое в бэкэнде преобразуется в expiry = now. Это может сбивать с толку клиентов. Также значение для expired может быть только true, поэтому здесь есть некоторая избыточность.

DELETE /restrictions/{id}

Ресурс остается постоянным (мягкое удаление), но не возвращается GET для коллекции, которая возвращает только не истекшие ограничения. Нет GET для индивидуальных ограничений.

PUT /restrictions/{id}/expiry
data = {}

Создает новый виртуальный ресурс (никаких других методов по этому пути), который представляет срок действия. Не уверен, что PUT без каких-либо данных идиоматичны.


В настоящее время я не планирую возвращать отдельные ограничения, и список всех ограничений по умолчанию будет возвращать только те, срок действия которых не истек.

Какой из этих методов вы считаете наиболее идиоматичным и очевидным для веб-службы RESTful?

Ответы [ 3 ]

0 голосов
/ 24 мая 2019

Какой из этих методов вы считаете наиболее идиоматичным и очевидным для веб-службы RESTful?

Если вы хотите использовать идиоматический REST, подумайте, как бы вы это делали с помощью сетиsite.

Вы, вероятно, начнете с GET /restrictions/{id}, и в дополнение к данным об ограничении будет форма - возможно, встроенная в представление, возможно, в представление другого ресурса, но доступная по ссылке.,Затем вы отправите эту форму, которая объединит поля в application/x-www-form-urlencoded заявку, включенную в POST запрос.Вы можете использовать любой URI в качестве действия формы (и, следовательно, target-uri запроса POST), но наиболее полезным будет, вероятно, POST /restrictions/{id}, потому что HTTP-совместимые клиенты будут знать, что делает недействительными любойранее кэшированные представления /restrictions/{id}.

Прямо сейчас я не планирую возвращать отдельные ограничения, и список всех ограничений по умолчанию будет возвращать только не просроченные.

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

Нет правила, согласно которому тип содержимого POST должен быть application/x-www-form-urlencoded.Вы можете публиковать другие представления, включая ваши собственные пользовательские типы, если это облегчает задачу (конечно, вы должны документировать тип, и единственными клиентами, которые собираются отправлять тип, являются те, которые его реализовали; большое преимущество дляСтандартные типы носителей - это то, что вы получаете множество клиентов «бесплатно».)

PUT и PATCH являются приемлемыми альтернативами, если изменение представлений напрямую представляется целесообразным.PUT (и, вероятно, PATCH, по логическому выводу) фактически не требует, чтобы сервер принимал запросы как есть:

Успешное PUT данного представления предполагает, что последующий GET натот же целевой ресурс приведет к отправке эквивалентного представления в ответе 200 (ОК).

Однако нет никакой гарантии, что такое изменение состояния будет наблюдаемым, поскольку на целевой ресурс могут действоватьдругие пользовательские агенты параллельно или могут подвергаться динамической обработке исходным сервером до получения любого последующего GET.Успешный ответ подразумевает только то, что намерение агента пользователя было достигнуто во время его обработки сервером происхождения.

В ответе должны соблюдаться соглашения, которые различают: «Я принял ваше представление как есть"из других ответов.

0 голосов
/ 24 мая 2019

Одним из немногих ограничений, которые имеет REST, является ограничение кеширование . Ограничения, как следует из названия, согласно Филдингу, не вариант , хотя он говорил о гипермедиа в этом контексте. Хотя общее правило применимо и здесь.

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

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

HTTP подробно описывает кэширование в RFC 7234 , а ответы могут указывать кешу, как долго ресурс должен считаться свежим через заголовок Cache-Control или Истекает заголовок. Если присутствуют оба, побеждает первый. Например, заголовок ответа, такой как Cache-Control: max-age=3600, определяет, что ответ должен считаться свежим на срок до 3600 секунд, в то время как Expires должен использовать формат даты и времени, указанный в RFC 7231 , такой как Expires: Fri, 24 May 2019 05:20:00 CET.

К сожалению, в RFC 7234 не говорится о том, как клиент может активно устанавливать такую ​​директиву, поскольку это считается задачей сервера. Cache-Control предоставляет некоторые заголовки запроса , хотя это больше указывает на то, что клиент либо примет или не примет устаревшие данные, но не указывает серверу установить соответствующую дату истечения срока действия. Обычно, если клиент не хочет, чтобы определенный ресурс был в дальнейшем доступен, он должен DELETE ресурс. Если вы прочитаете DELETE , вы можете быть удивлены тем, что это на самом деле не гарантирует, что ресурс когда-либо будет вообще удален. Все это говорит о том, что после успешной обработки такого запроса сопоставление URI с ресурсом удаляется. Доступен ли один и тот же ресурс через другой URI или нет, это не отдельная история. «Настройка» DELETE с каким-либо параметром для удаления ресурса через определенное время может работать для вашего API, хотя может быть непонятным для различных типов API, поэтому в общем случае это не рекомендуется.

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

Если все другие методы HTTP не соответствуют требованиям, следует принять POST , так как здесь сервер будет обрабатывать запрос в соответствии со своей собственной семантикой. Он может применять разные эвристики и при получении разных полезных нагрузок на одну и ту же конечную точку. Если вам нужно разработать такую ​​функцию в Интернете, у вас может быть страница редактирования записи, где у вас есть возможность установить срок действия. После нажатия кнопки отправки формы ваш браузер выполняет запрос POST, включая дату истечения срока действия, и сервер будет знать, что делать, основываясь на определенных эвристиках, доступных на сервере. То есть наличие в запросе поля даты истечения срока действия может дать серверу указание поставить в очередь удаление записи, обновить метаданные даты истечения срока действия целевого ресурса и вернуть обновленный заголовок Cache-Control: max-age=... или Expires: ... для входящих запросов. сообщать кешам о том, что не отправлены кэшированные ответы этого ресурса после этого момента времени.

Обычно небезопасные операции, такие как POST, PUT или DELETE, делают недействительными кэшированные ответы целевого ресурса по умолчанию, в случае, когда два пользователя выполняют кешируемые GET запросы против сервер, имеющий промежуточный кэш, который отличается от промежуточного кеша другого пользователя, и пользователь 1 теперь истекает ресурс источника, может быть случай, когда пользователь 2 все еще будет обслуживаться «своим» промежуточным кешем для цели ресурс, даже несмотря на то, что ресурс уже был удален на исходном сервере, поскольку его промежуточный кэш по-прежнему считает ответ достаточно свежим и поэтому использует значение 2 с этим сохраненным ответом. Кэшированный ответ целевого URI в кеше пользователя 1 уже должен был быть удален первоначальным запросом POST, но также любой в конечном итоге кэшируемый ответ мог бы вернуть обновленный заголовок кэша и, таким образом, привести к истечению срока действия в указанный момент времени. Поэтому важно установить значения времени для кэша не слишком высокими в будущем, но и не короткими, чтобы кэширование стало бесполезным.

Для ресурсов, которые могут быть критически важны для удаления и не обслуживаются кэшами, для предотвращения вышеупомянутого случая, вероятно, лучше всего указать Cache-Control: no-cache в целом, чтобы такие записи не сохранялись в кэшах далее, а запросы напрямую обрабатывается самим API / сервером.

Чтобы подвести итог этого поста, что-то вроде момента истечения срока действия следует рассматривать как метаданные ресурса, а не как основные данные. Хотя DELETE на первый взгляд может звучать замечательно, через некоторое время он не поддерживает удаление, и другой API может выполнить такой запрос немедленно, кроме того, что вообще не гарантирует реального удаления этого ресурса. POST, как универсальный набор инструментов HTTP, или другие операции HTTP, такие как PUT или PATCH, также могут быть использованы здесь, даже если последние "работают" при условии, что тело запроса принадлежит к фактическим данным ресурса. Вам также следует рассмотреть возможность кэширования в вашем проекте и использовать Cache-Control: max-age=... или Expires: ..., если ваш ресурс не критичен, или Cache-Control: no-cache в случае ресурсов, которые никогда не должны (по какой-либо причине) возвращать устаревшую информацию клиентам. Независимо от используемого вами метода HTTP, вам также следует подумать о том, как сервер разрешает клиенту устанавливать эту опцию в целом. Как и в Интернете, решение на основе форм позволяет избежать внеполосной информации и, таким образом, упрощает взаимодействие с API в целом, поскольку вся информация уже предоставлена ​​или доступна по дополнительным ссылкам.

0 голосов
/ 24 мая 2019

Если ресурс вернет значение 404 после истечения срока действия, DELETE отличный способ для этого.

...