Руководство по разработке REST API

Я занимаюсь разработкой общедоступного API для нашего интерфейса REST. Одной из возникших проблем было использование HTTP-глаголов, особенно глагола DELETE.

Мы хотим предоставить методы для запуска/остановки или выполнения/отмены определенного задания. Два варианта дизайна API для этих двух:

РАЗМЕСТИТЬ

http://localhost/api/campaignrun/1

Выполнить запуск кампании с идентификатором 1

УДАЛИТЬ

http://localhost/api/campaignrun/1

Прервать запуск кампании с идентификатором 1

В качестве альтернативы...

РАЗМЕСТИТЬ

http://localhost/api/campaignrun/1

{ action=execute}

Выполнить запуск кампании с идентификатором 1

РАЗМЕСТИТЬ

http://localhost/api/campaignrun/1

{ action=abort }

Прервать запуск кампании с идентификатором 1

Если есть мой любимый, какой из них более RESTful?


person gavins    schedule 17.04.2013    source источник


Ответы (5)


Можно ли перезапустить остановленное задание? Если это так, я предлагаю вам использовать POST, поскольку на самом деле вы не удаляете какой-либо ресурс. Однако вы можете изменить URL-адреса, чтобы лучше указать, чего вы пытаетесь достичь:

РАЗМЕСТИТЬ

http://localhost/api/campaignrun/1/start

и

РАЗМЕСТИТЬ

http://localhost/api/campaignrun/1/stop

Таким образом, нет необходимости предоставлять тело запроса для указания типа действия.

Примечание: для меня DELETE означает, что кампания будет удалена навсегда и, следовательно, не может быть перезапущена. Следовательно, 404 будет возвращен, если клиент попытается получить доступ к ресурсу.

person matsev    schedule 17.04.2013
comment
Это шаблон RPC. start и stop — это глаголы, которые подразумевают RPC. Вы должны найти собственное существительное, чтобы описать, что вы пытаетесь контролировать. например создать представление, описывающее выполняемую работу. Используйте POST для создания (запуска) задания. GET для чтения состояния задания. УДАЛИТЬ, чтобы остановить (убить) задание. и т. д. - person Filip; 17.04.2013

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

PUT http://localhost/api/campaignrun/1

{ action: abord }

Этот API ясно говорит о его намерениях: у вас есть campaignruns (лучше сохранить это множественное число), вы хотите провести кампанию с {id} = 1, и у этого ресурса есть атрибут action, который я хочу >обновить.

Таким образом, вы поддерживаете соответствие своего API идемпотентности HTTP-глаголов: PUT должно быть идемпотентным, POST не должен. В вашем случае это означает, что независимо от того, сколько раз пользователь нажимает на указанный выше запрос, результат один и тот же: запуск кампании с id=1 будет прерван.

Примечание. Я вижу, вы приняли ответ, в котором предлагаются глаголы в URI, а затем используется для них POST. Этот пост — не место для споров за или против REST, но, поскольку ваш вопрос касается какой дизайн более RESTful, вам следует дважды подумать. Вы можете проверить эту очень хорошую 38-страничную бесплатную электронную книгу, в которой рассказывается о передовых методах разработки API. . Среди прочего, предлагается не использовать глаголы в базовых URL-адресах, за исключением очень редких случаев. Посмотрите, будет полезно!

person zafeiris.m    schedule 17.04.2013

Первый более «спокойный». Единственная проблема, с которой вы столкнетесь, - это если вам нужно будет удалить, а не прервать запуск кампании в будущем. Вы всегда можете просто передать действие УДАЛИТЬ, если вам потребуется функция удаления записи запуска кампании в будущем.

person Brian Ogden    schedule 17.04.2013

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

person Donal Fellows    schedule 17.04.2013

Как многие здесь заявляли, УДАЛЕНИЕ на ресурсе означает, что соответствующий campaignrun больше недоступен (после этого должна вернуться ошибка 404 Not Found). Я предполагаю, что это не намерение прервать кампанию.

Следующее будет более совместимо с REST для любых альтернатив, упомянутых в вопросе:

СООБЩЕНИЕ

http://localhost/api/campaignruns

Обратите внимание на существительное во множественном числе (более RESTful, коллекция->экземпляр->коллекция->экземпляр...).

Этот запрос создает кампанию. Допустим, созданный идентификатор campaignrun равен 1.

СООБЩЕНИЕ

http://localhost/api/campaignruns/1/operations

{
    "operation": "execute"
}

СООБЩЕНИЕ

http://localhost/api/campaignruns/1/operations

{
    "operation": "abort"
}
  • API операций поддерживает следующие методы HTTP: GET, POST.
  • API operations может быть реализован как асинхронный вызов (возвращается 202 Accepted).

Допустим, идентификатор операции прервать равен 2.

Вот как это выглядит (предполагая асинхронную операцию) сразу после POST:

ПОЛУЧИТЬ

http://localhost/api/campaignruns/1/operations/2

Response:

{
    "id": 2,
    "operation": "abort",
    "status": "processing"
}

Вот как это должно выглядеть после завершения:

ПОЛУЧИТЬ

http://localhost/api/campaignruns/1/operations/2

Response:

{
    "id": 2,
    "operation": "abort",
    "status": "completed"
}
person Genry    schedule 02.04.2015