Представьте, что веб-приложение хранит некоторый ресурс данных с некоторым идентификатором, который хранит три вложения (например, pdf) для каждого элемента данных.
Схема URL
data/{id}/attachment1
data/{id}/attachment2
data/{id}/attachment3
Существует API RESTful для вложений, предоставляющих операции GET/PUT/DELETE, реализующие операции CRUD на стороне сервера.
Если id равен 123, я хотел бы выполнить операцию, в которой
- attachment1 заменяется новым вложением (таким образом, что
GET file/123/attachment1
возвращает новое вложение) - attachment2 удаляется (так что
GET file/123/attachment2
возвращает 404) - attachment3 остается неизменным.
Обновление должно быть атомарным - полное обновление выполняется сервером или вообще ничего.
Применение простых PUT file/123/attachment1
и DELETE file/123/attachment2
не является атомарным, так как клиент может потерпеть крах после PUT, и на сервере нет намека на то, что он должен сделать откат в этом случае.
Итак, как мне выполнить операцию с помощью RESTful?
Я думал о двух решениях, но оба они не кажутся 100% RESTful:
- Используйте PATCH (может быть PUT, но PATCH лучше отражает семантику частичное обновление) с multipart/form-data по данным /123: multipart/form-data - это последовательность объектов, состоящих из нового "application/pdf", связанное с полем "attachment1" и то, что будет представлять нулевое значение для обозначения удаления attachment2.
Хотя это обеспечивает атомарность, я сомневаюсь, что это RESTful, поскольку я перегружаю метод PATCH, используя разные списки параметров, что нарушает ограничение унифицированного интерфейса.
- Используйте ресурс, представляющий транзакцию. Я мог бы отправить данные ID 123
URL-адрес транзакции, который будет создавать ресурс транзакции
представляющий копию текущего состояния хранимого ресурса данных
на сервере, например. транзакции/данные/123. Теперь я могу вызвать PUT и
УДАЛИТЬ на вложения этого временного ресурса (например,
DELETE transaction/data/123/attachment2
) и сообщить фиксация этой версии ресурса на сервере через PUT on транзакции/данные/123. Это обеспечивает атомарность, когда приходится реализовать дополнительную логику на стороне сервера для работы с несколькими клиентами изменение того же ресурса и разбитых клиентов, которые никогда не совершались.
Хотя это, похоже, согласуется с REST, похоже, это нарушает противоречие безгражданства. Состояние транзакционного ресурса - это не состояние службы, а состояние приложения, поскольку каждый транзакционный ресурс связан с одним клиентом.
Я как бы застрял здесь, поэтому любые идеи были бы полезны, спасибо!