Смешивание REST с не RESTful вызовами API - PullRequest
0 голосов
/ 06 февраля 2019

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

Для простоты мы скажем, что API - это timer.

  • Одновременно пользователь может иметь только 1 активную timer.
  • API имеет 2 функциональные конечные точки start и stop.
  • Когда пользователь start устанавливает таймер, он POST сообщает некоторые данные, относящиеся к timer, который создает новый timer, если у него еще не запущен timer.
  • Вызов stop на timer обновляет timer, чтобы пометить его как неактивный.

В настоящее время у меня есть эта настройка следующим образом:

Таймер запуска:

POST /api/v1/timer
Body: [
    'thing1' => 'something',
    'thing2' => 'somethingelse
]

Response: 204

Таймер остановки:

PUT /api/v1/timer/stop
Body:

Response: 204

Поскольку у пользователя может быть активна только 1 timer, возвращать timer id не имеет смысла, как вболее традиционный вызов CRUD.

Я читал некоторые посты, в которых предлагается использовать POST метод для вызова stop, чтобы вызвать останов вместо PUT.Я полагаю, что это тоже имеет смысл ... это действительно ломается, когда вы не имеете дело с традиционным ресурсом.

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

Любой ввод здесь будет принят с благодарностью.

1 Ответ

0 голосов
/ 07 февраля 2019

Подумайте, как бы вы реализовали это требование на веб-сайте.

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

Когда вы отправляете форму, браузер создает запрос на основе правил обработки формы HTML.Поскольку это небезопасная операция, метод, вероятно, будет публикацией, а данные формы будут application / x-www-form-urlencoded в теле сообщения.

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

Когда вы перезагрузите эту страницу, ссылка «старт» исчезнет, ​​и вместо этого будет «остановка»" ссылка на сайт.Работа с этой ссылкой будет практически такой же -> нажатие на ссылку приведет вас к форме, отправит форму обратно на исходную страницу и лишит законной силы предыдущее представление.Когда вы перезагружаете страницу, таймер выключается, и стартовая ссылка снова становится доступной.

GET /DarthVaderYellowMerrigold

GET /DarthVaderYellowMerrigold/start
POST /DarthVaderYellowMerrigold
GET /DarthVaderYellowMerrigold

GET /DarthVaderYellowMerrigold/stop
POST /DarthVaderYellowMerrigold
GET /DarthVaderYellowMerrigold

Есть несколько вещей, которые вы можете сделать, чтобы убрать это (возвращение нового представления в ответ на успешный POST,например, с соответствующими заголовками Content-Location, чтобы клиенту не нужно было извлекать данные), но основная идея - это звук.

Сделайте это машиночитаемым способом, и вы самиAPI REST.

Выполнение этого в основном означает документирование того, как машина должна понимать, для чего предназначена каждая ссылка.«Чтобы перейти к форме таймера запуска, найдите эту ссылку; чтобы перейти к форме таймера остановки, найдите эту ссылку».

Возможно, вы оставите HTTP и URI в покое, но разумно заменить HTMLнапример, с одним из типов гипермедиа JSON.Или поместить ссылки в заголовки HTML, а не в представление.

Конечно, у HTML есть непосредственное преимущество: вы можете просто пройтись по API "вручную" и убедиться, что все работает, используя ваш любимыйнастольный браузер.Компромиссов предостаточно.

...