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