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