在REST中进行交易?
我想知道我们如何在REST中实现以下用例。是否有可能在不损害概念模型的情况下做?
在单个事务范围内读取或者更新多个资源。例如,将$ 100从Bob的银行帐户转入John的帐户。
据我所知,实现这一目标的唯一方法是作弊。我们可以发布到与John或者Bob关联的资源,并使用单个事务执行整个操作。就我而言,这破坏了REST架构,因为我们实际上是通过POST来传送RPC调用的通道,而不是真正对单个资源进行操作。
解决方案
我们必须推出自己的"交易ID"类型的TX管理。因此,将有4个调用:
http://service/transaction (some sort of tx request) http://service/bankaccount/bob (give tx id) http://service/bankaccount/john (give tx id) http://service/transaction (request to commit)
我们必须处理动作在DB(如果负载平衡)或者内存等中的存储,然后处理提交,回滚,超时。
在公园里,这并不是真正令人愉快的一天。
我想我们可以在网址/资源中包含TAN:
- PUT /交易以获取ID(例如" 1")
- [PUT,GET,POST,等等] / 1 / account / bob
- [PUT,GET,POST,等等] / 1 /帐户/帐单
- ID为1的删除/交易
只是一个主意。
考虑一个RESTful购物篮方案。从概念上讲,购物篮是事务包装器。可以将多个项目添加到购物篮中,然后提交该购物篮以处理订单,我们可以将Bob的帐户条目添加到事务包装器中,然后将Bill的帐户条目添加到包装器中。当所有零件都准备就绪时,我们可以将所有组件零件进行POST / PUT事务包装。
我认为在这种情况下打破REST的纯理论是完全可以接受的。无论如何,我认为REST中实际上没有任何内容表明我们无法在需要它的业务案例中接触依赖对象。
我真的认为,当我们只需要利用数据库来执行此操作时,创建一个自定义事务管理器就不会花额外的钱。
在简单的情况下(没有分布式资源),我们可以将事务视为资源,创建事务的行为可以达到最终目标。
因此,要在<url-base> / account / a和<url-base> / account / b之间进行转移,我们可以将以下内容发布到<url-base> / transfer中。
<transfer> <from><url-base>/account/a</from> <to><url-base>/account/b</to> <amount>50</amount> </transfer>
这将创建一个新的传输资源并返回新的传输URL,例如" <url-base> / transfer / 256"。
然后,在成功过帐的那一刻,在服务器上执行"真实"交易,并将金额从一个帐户中删除并添加到另一个帐户中。
但是,这不包括分布式交易(例如,假设" a"存放在一项服务后面的一家银行,而" b"存放在另一项服务后面的另一家银行)以不需要分布式交易的方式"。