Скажем, у вас есть ресурс Person, и часть его представления включает в себя значение Location, которое может иметь такие значения, как «дома», «в школе» и «на работе». Как бы вы НАСТОЯТЕЛЬНО разоблачали такие действия, как «иди домой», «иди на работу», «иди в школу» и т. Д.? Для обсуждения давайте оговорим, что эти действия занимают время, поэтому они выполняются асинхронно, и существуют различные способы, которыми они могут потерпеть неудачу (нет доступных средств транспортировки, поломка транспорта во время путешествия, другой стихийный бедствие и т. Д.) , Кроме того, ресурс Person имеет другие атрибуты и связанные операции, которые влияют на эти атрибуты (например, атрибут = уровень энергии, операции = питание / сон / тренировка).
Опция 1 : Перегрузка POST для ресурса Person, предоставляя входной параметр, указывающий, что вы хотите, чтобы человек сделал (например, action = go-to-school). Верните 202 из сообщения POST и предоставьте атрибуты состояния незавершенного действия в представлении Person, которые клиент может ПОЛУЧИТЬ, чтобы наблюдать за прогрессом и успехом / неудачей.
Преимущества: делает все просто.
Недостатки: равносильно туннелированию. Происходящее действие скрывается в полезной нагрузке, а не отображается в URI, глаголе, заголовках и т. Д. У глагола POST в этом ресурсе нет единого семантического значения.
Вариант 2 : Используйте PUT, чтобы установить местоположение человека в том состоянии, в котором вы хотите, чтобы он находился. Верните 202 из PUT и предоставьте атрибуты незавершенного действия для опроса статуса через GET.
Преимущества : Не уверен, что я вижу.
Недостатки : действительно, это просто туннелирование с другим глаголом. Кроме того, в некоторых случаях это не работает (как сон, так и прием пищи увеличивают уровень энергии, поэтому перевод значения энергии на более высокое значение неоднозначен с точки зрения того, какое действие вы хотите выполнить для ресурса).
Опция 3 : предоставить общий ресурс контроллера, который работает с объектами Person. Например, создайте ресурс PersonActivityManager, который принимает запросы POST с аргументами, которые идентифицируют целевой объект Person и запрошенное действие. POST может возвратить ресурс PersonActivity, чтобы представить текущее действие, которое клиент может ПОЛУЧИТЬ, чтобы отслеживать прогресс и успех / сбой.
Преимущества : выглядит немного чище, если отделить активность и ее статус от ресурса Person.
Недостатки : Теперь мы переместили туннелирование на ресурс PersonActivityManager.
Вариант 4 :
Установите отдельные ресурсы контроллера для каждого поддерживаемого действия, например, ресурс ToWorkTransporter, который принимает запросы POST с аргументом (или элементом URI), который идентифицирует Person, плюс ToHomeTransporter, ToSchoolTransporter, MealServer, Sleeper и Exerciser. Каждый из них возвращает соответствующий ресурс мониторинга задач (Commute, Meal, Slumber, Workout) из своего метода POST, который клиент может отслеживать с помощью GET.
Преимущества : ОК, мы наконец-то устранили туннелирование. Каждый POST означает только одну вещь.
Недостатки : Теперь говорилось о большом количестве ресурсов (возможно, мы могли бы объединить транспортеры в один Транспортер, который принимает аргумент назначения). И некоторые из них довольно семантически придуманы (Спящий?). Это может быть более RESTful, но это практично?