Какой самый RESTful способ обновить ресурс неидемпотентным способом?

Какой самый RESTful способ обновить часть ресурса, где генерация этого ресурса выполняется на стороне сервера, а не на стороне клиента. Это не идемпотентное действие, так как вспомогательные данные на сервере могут меняться между запросами.

Я создаю Rest API, и я пришел к выбору дизайна, где я совершенно уверен в том, как двигаться дальше.

У меня есть ресурс, который я хочу обновить, который включает создание большого BLOB-объекта JSON на основе данных поддержки, а затем сохранение этого BLOB-объекта в базу данных перед его отправкой обратно пользователю.

У меня вопрос, какой самый RESTful способ выполнить это действие? Поскольку клиент не выполняет расчеты, и он также не является идемпотентным, поскольку набор данных может меняться между вызовами, я чувствую, что использовать PUT неестественно.

Я остановился на POST, но это тоже не правильно.

Третий вариант - иметь подресурс, который описывает действие обновления - это тоже не правильно.

Например, у меня есть документ:

GET /document/<documentId>

который будет возвращать что-то вроде:

"body": {
    "createdAt": "2019-01-01 12:00:00",
    "updatedAt": "2019-01-01 13:00:00",
    "name": "example",
    "location": "example",
    "city": "example"
}

Эти поля генерируются сервером при создании документа, клиент не обновляет их.

Чтобы позволить клиенту сигнализировать, что он хочет, чтобы сервер обновил документ, я остановился на:

POST /document/<documentId>
"body": {
   "param1": "updatedparam1",
   "param2": "updatedparam2"
}

Альтернативным подходом было бы сделать что-то вроде:

POST /document/<documentId>/refresh
"body": {...}

но это больше похоже на вызов RPC, чем на REST.

Это имеет смысл логически? Я не видел много предложений о том, что POST может быть для одного ресурса, а не для коллекции.

Пожалуйста, дайте мне знать, если я могу расширить что-нибудь, я бился головой об этом некоторое время и, вероятно, что-то пропустил.

Всего 1 ответ


Я остановился на POST, но это тоже не правильно.

POST в порядке .

Семантика HTTP включает в себя правила о признании недействительными кэшированных представлений ресурсов. Предположительно, когда вы говорите серверу перегенерировать документ, вы не хотите продолжать использовать старую копию самостоятельно. Таким образом, целевой URI запроса должен совпадать с тем, который вы используете для получения ресурса.

Так:

POST /document/<documentId>

Это хорошее начало.

Альтернативой, при условии совпадения семантики, будет использование PATCH - это правильный выбор, если вы предлагаете заменяющие значения для представления. В этом случае тело запроса должно быть «документом исправления». Вы, конечно, можете определить свой собственный тип документа патча; Общие клиенты уже могут понимать один или несколько стандартов RFC-6902: JSON Patch или RFC-7386: JSON Merge Patch, так что вы можете потенциально сохранить часть работы, поддерживая один или несколько стандартных форматов.

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

Отчасти REST заключается в том, что ресурсы поддерживают единый интерфейс - «отдельные ресурсы» и «ресурсы коллекции» выглядят одинаково . Исторически нам немного не повезло с ранними спецификациями для POST , которые легко были неверно истолкованы как CREATE.

Но обычные клиенты не знают или не заботятся о том, является ли ресурс, указанный вами в веб-форме, «ресурсом для сбора»; он просто упаковывает данные и отправляет запрос, будучи уверенным, что сервер будет знать, что делать.


Есть идеи?

10000