Я нахожусь в процессе написания RESTful API. По большей части все работает отлично, но бывают случаи, когда я не работаю с ресурсом, и все начинает ломаться. Хотя существует миллион способов решить проблему, с которой я столкнулся, я ищу отзывы о том, какой из них был бы самым идеальным.
Для простоты скажем, что API — это timer.
timer.start и stop.start устанавливает таймер, он записывает некоторые данные, связанные с POST, который создает новый timer, если у него еще не запущен timer.timer на stop обновляет timer, чтобы пометить его как неактивный.В настоящее время у меня есть эта настройка следующим образом:
Стартовый таймер:
POST /api/v1/timer
Body: [
'thing1' => 'something',
'thing2' => 'somethingelse
]
Response: 204
Остановить таймер:
PUT /api/v1/timer/stop
Body:
Response: 204
Поскольку у пользователя может быть активен только 1 timer, казалось нецелесообразным возвращать timertimer, как в более традиционном вызове CRUD.
Я прочитал некоторые сообщения, в которых предлагается использовать метод id для вызова POST, чтобы вызвать остановку вместо stop. Я полагаю, что это тоже имеет смысл ... это действительно ломается, когда вы не имеете дело с традиционным ресурсом.
Конечно, я мог бы также переписать его, чтобы он возвращал ресурс PUT, но для меня это увеличивает нагрузку на клиента, который должен затем отслеживать timertimer, когда он хочет остановить (или удалить) активный таймер.
Любой вклад здесь будет принят с благодарностью.






Подумайте, как бы вы реализовали это требование на веб-сайте.
Вы бы смотрели на какую-то веб-страницу, относящуюся к текущему пользователю. Там будет ссылка с надписью start. Вы получите эту ссылку, и она вызовет форму, которая даст вам возможность переопределить параметры по умолчанию, связанные с запуском таймера.
Когда вы отправляете форму, браузер создает запрос на основе правил обработки 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, чтобы клиенту не нужно было извлекать данные), но основная идея звучит.
Сделайте это машиночитаемым способом, и у вас будет REST API.
Это в основном означает документирование того, как машина должна понимать, для чего предназначена каждая ссылка. "Чтобы перейти к форме запуска таймера, ищите эту ссылку; чтобы перейти к форме остановки таймера, ищите эту ссылку".
Вы, вероятно, оставите HTTP и URI в покое, но разумно заменить HTML, например, одним из типов гипермедиа JSON. Или размещать ссылки в заголовках HTML, а не в представлении.
Конечно, у HTML есть непосредственное преимущество, заключающееся в том, что вы можете просто пройтись по API «вручную» и убедиться, что все работает, используя ваш любимый настольный браузер. Компромиссов предостаточно.
Думаю, мне следует уточнить, что это API OAuth2. Это не будет использоваться или потребляться HTML.