RESTful原子更新多个资源?

mts*_*tsz 24 rest transactions multipartform-data crud atomic

想象一下,一个web应用程序存储一些数据资源,其中一些id存储每个数据的三个附件(例如pdf).

URL方案是

data/{id}/attachment1
data/{id}/attachment2
data/{id}/attachment3
Run Code Online (Sandbox Code Playgroud)

存在用于在服务器端实现CRUD操作的GET/PUT/DELETE操作的附件的RESTful API.

让id为123,我想执行一个操作

  • attachment1被新附件替换(例如GET file/123/attachment1返回新附件)
  • attachment2被删除(这样GET file/123/attachment2返回404)
  • attachment3保持不变.

更新应该是原子 -由服务器或什么都没有进行完整的更新.

运用简单PUT file/123/attachment1DELETE file/123/attachment2不是原子,因为客户可以在PUT之后崩溃,并且服务器有没有暗示他应该在这种情况下,做了回退.

那么如何以RESTful方式实现操作呢?

我想过两个解决方案,但它们似乎都不是100%RESTful:

  • 使用PATCH(可能是PUT,但PATCH更好地反映了部分更新的语义)和数据/ 123上的multipart/form-data:multipart/form-data是一个由新的"application/pdf"组成的实体序列使用字段"attachment1"和表示删除attachment2的空值的东西.

虽然这确保了原子性,但我怀疑这是RESTful,因为我使用不同的参数列表重载PATCH方法,这违反了统一接口约束.

  • 使用表示事务的资源.我可以将数据id 123发布到事务URL,该事务URL将创建表示存储在服务器上的数据资源的当前状态的副本的事务资源,例如事务/数据/ 123.现在,我可以在此临时资源(例如DELETE transaction/data/123/attachment2)的附件上调用PUT和DELETE,并通过事务/ data/123上的PUT将此版本资源的提交传达给服务器.这确保了原子性,同时必须实现额外的服务器端逻辑来处理更改相同资源的多个客户端以及从未提交的崩溃客户端.

虽然这似乎与REST一致,但似乎违反了无国籍的约束.事务资源的状态不是服务状态而是应用程序状态,因为每个事务资源都与单个客户端相关联.

我有点被困在这里,所以任何想法都会有所帮助,谢谢!

Wil*_*ung 16

您想使用第二个选项,即事务选项.

您缺少的是创建交易:

POST /transaction

HTTP/1.1 301 Moved Permanently
Location: /transaction/1234
Run Code Online (Sandbox Code Playgroud)

现在您拥有一个一等公民的交易资源.您可以添加它,从中删除,查询以查看其当前内容,然后最终提交或删除(即回滚)事务.

当交易正在进行时,它只是另一种资源.这里没有客户状态.任何人都可以添加到此交易中.

完成所有操作后,服务器会使用一些超出范围的内部事务机制一次性应用更改.

您可以在事务子操作中捕获诸如Etags和if-modified标头之类的内容,这样当它们全部应用时,您就会知道背后的某些内容没有发生变化.

  • 您可以像查看购物车一样查看交易.在购物车中,客户建立他们的交易随着时间的推移,然后他们只是通过结账过程,最终结束他们"确认"或"取消"订单.当你用这些词汇来看待它时,它会更有意义.但是在10,000英尺处,它们基本上是同一个问题."这是我想要做的所有事情的清单 - 现在,GO!" 购物车绑定到特定用户的事实是安全/身份问题,而不是"州"与"无国籍"问题. (8认同)
  • @Niko Bellic您可以简单地将事务链接发布到/ commit资源。您可以将事务状态(COMMITED,UNCOMMITED)作为资源的属性,完成后将其更改为COMMITED并放入资源。那也可以正常工作。查看交易资源的另一种方式就像是购物车。购物车只是一种特殊的交易类型。 (2认同)

the*_*rmz 5

非常有趣的问题.卢加诺大学(瑞士)的CS教授写了一些关于这种情况的幻灯片:

http://www.slideshare.net/cesare.pautasso/atomic-transactions-for-the-rest-of-us

但是,我不确定他提供的解决方案是完全RESTful的,因为它在服务器端似乎没有真正的无状态.

老实说,既然交易本身是由多个州组成的,我认为这个问题不会有完全RESTful的解决方案.