Как разработать REST API для не-CRUD "команд", например, активировать и деактивировать ресурс?
Прежде чем я решил задать этот вопрос, я долго искал ответ, но я не нашел удовлетворительного. (например, Примеры лучших веб-интерфейсов SOAP/REST/RPC и почему они вам нравятся? И что с ними не так?)
И проблема на самом деле довольно проста. У меня есть объект/ресурс с именем Account. Мой REST API поддерживает все CRUD с GET, POST, PUT и DELETE уже с правильной обработкой ошибок, кодами состояния и т.д.
Кроме того, однако я хочу открыть API ( "команда" ) для активации и деактивации выбранного ресурса учетной записи.
Даже если "isActive" является свойством учетной записи, я не хочу использовать только обновление из моего CRUD всей учетной записи.
Я знаю, что легко нарушить принципы REST и сделать дизайн стиля RPC таким дизайном, как это:
PUT/api/account/: accountId/activate
PUT/api/account/: accountId/deactivate
Итак, каково наилучшее решение для этого варианта использования?
Моя нынешняя идея - использовать PUT и DELETE глаголы, подобные этому (чтобы рассматривать его как под-ресурс), как предлагается здесь http://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api#restful:
PUT/api/account/: accountId/isActive//для активации
DELETE/api/account/: accountId/isActive//для деактивации
Каковы ваши решения?
Ответы
Ответ 1
Как насчет того, чтобы придумать существительное для функции, которую вы хотите изменить - "статус" в этом случае. Тогда это станет вспомогательным ресурсом родительского объекта. Поэтому для вашего случая я бы моделировал URI следующим образом:
/api/accounts/{accountId}/status
Если семантика 'update' является идемпотентной, то PUT будет наиболее подходящей, иначе это должно быть POST (например, если не задействованы и недействительны службой). Фактическая полезная нагрузка будет включать дескриптор для нового состояния.
Обратите внимание, что я плюрализую "учетные записи", так как вы можете иметь несколько из них, но статус сингулярный, поскольку ваша учетная запись может иметь только одно состояние.
Ответ 2
Метод POST создаст учетную запись ресурса. Active можно рассматривать как одно из свойств ресурса "account". Следовательно, это должен быть запрос PUT.
Я бы сказал, что даже деактивация должна быть запросом PUT, поскольку ресурс учетной записи будет существовать.
Чтобы активировать учетную запись, вы можете установить свойство на ресурсе. То есть:
/api/account/{accountId}?activate=true
Чтобы деактивировать:
/api/account/{accountId}?activate=false
Запрос GET в учетной записи возвращает JSON с активирующим значением в нем.
Запрос DELETE должен полностью удалить ресурс учетной записи.
Ответ 3
Во-первых, PUT
подходит по сравнению с POST
, потому что вы создаете ресурс в уже известном месте. И, я думаю, нет дилеммы о DELETE
. Итак, на первый взгляд, ваш нынешний подход, по-видимому, превзошел альтернативы.
Я так же думал, пока не выполнил свой собственный REST api, в котором я хотел, чтобы администратор мог установить учетную запись в деактивированном, но не удаленном, просто "запрещенном" состоянии. Когда я немного подумал, я решил сделать это наоборот.
Позвольте мне объяснить. Мне нравится, когда ресурс activation
"активирует учетную запись". Поэтому, если существует такой URL, как /account/foo/activation
, это может означать, что учетная запись не активирована и, пользователь имеет право ее активировать. Если он не существует, учетная запись либо уже активирована , либо в запрещенном состоянии.
Следовательно, единственная рациональная вещь, которую нужно сделать, чтобы активировать учетную запись, - это попробовать и DELETE
ресурс. И, чтобы активировать активацию, администратор должен был PUT
ресурс активации.
Теперь вопрос, который приходит на ум, заключается в том, как отличить запрещенную учетную запись от уже активированной. Но поскольку запрет можно рассматривать как ресурс, вы можете создать коллекцию ресурсов /account/foo/ban
. Чтобы заблокировать учетную запись, возможно, на определенный период времени, вы просто POST
ресурс в этой коллекции, содержащий все детали запрета.
Ответ 4
PATCH - наиболее подходящий метод в этом случае. Подробнее см. URL-адрес RESTful для "Активация"