想象一下,一个网络应用程序存储一些数据资源,这些数据资源有一些id,每个数据存储三个附件(例如pdf)。多个资源的RESTful原子更新?
的URL方案是
data/{id}/attachment1
data/{id}/attachment2
data/{id}/attachment3
的REST风格的API存在提供GET/PUT附件/ DELETE在服务器端执行CRUD操作操作。
又让ID是123,想以执行其中
- 附件1由一个新的附件替换一个操作(使得
GET file/123/attachment1
返回一个新的附件) - attachment2被删除(使得即
GET file/123/attachment2
返回404) - attachment3保持不变。
该更新应该是原子 - 完整的更新是由服务器执行或根本没有。
应用简单的PUT file/123/attachment1
和DELETE file/123/attachment2
不是原子的,因为在PUT之后客户端可能会崩溃,并且服务器没有提示他应该在这种情况下进行回滚。
那么如何以RESTful的方式实现操作?
我想过两种解决方案,但他们似乎都没有100%的RESTful:
- 使用Patch(可放,但PATCH能更好地反映的 的部分更新的语义)与多/表格数据/ 123:多部分/表格数据是由与字段“attachment1”和 相关联的新的 “application/pdf”组成的实体序列,其将代表空值以表示空值删除 附件2。
虽然这确保了原子性,但我怀疑这是RESTful,因为我使用不同的参数列表来重载PATCH方法,这违反了统一接口约束。
- 使用表示事务的资源。我可以将数据ID 123 发布到事务URL,该事务URL将创建表示服务器上存储的数据资源 的当前状态的副本的事务资源 ,例如,交易/数据/ 123。现在我可以调用PUT和 DELETE这个临时资源的附件(例如
DELETE transaction/data/123/attachment2
)并且通过 transaction/data/123将此版本的资源提交到服务器的服务器通信 。这确保了原子性,同时必须实现额外的服务器端逻辑来处理多个客户端 更改相同的资源和崩溃的客户端永远不会提交。
虽然这似乎与REST一致,但似乎违反了无国籍的限制。事务资源的状态不是服务状态,而是应用程序状态,因为每个事务资源都与单个客户端相关联。
我有点卡在这里,所以任何想法会有所帮助,谢谢!
第二种方法的好处是提供了一个很好的数据更改历史记录,并可能允许您跳过某些日志记录。 – Jasper 2012-04-06 07:07:37
@mtsz我现在正在努力解决这个问题。我喜欢下面选择的答案,但创建短暂的临时生命周期的交易资源似乎有很多工作要做。你认为给原子事务执行一个像“switcheroo”这样的名称并创建一个执行该事务的特定Web服务会很糟糕吗?例如,具有{fileId:123}的主体的POST/doSwitcheroo ....该服务将具有逻辑地以文件形式执行上面在ID为123的文件中描述的动作012 – 2015-11-11 02:22:57