On Wed, May 7, 2008 at 7:57 AM, Toby Corkindale <[EMAIL PROTECTED]> wrote: > Hi Adam, > > > > On Wed, May 07, 2008 at 03:30:12PM +1000, Adam Clarke wrote: > > On 07/05/2008, at 11:05 AM, Toby Corkindale wrote: > > > >> Ah, I was thinking of transactions vs a REST API, eg: > >> PUT /user/1234/account_balance?subtract=1 > >> POST /user/4567/account_balance?add=1 > >> Since those are two separate HTTP requests, and REST specifically states > >> you > >> cannot maintain state on the server, how would you perform those two > >> operations inside a transaction? > >> > >> (My "solution" is to implement it in one request, like: > >> PUT /user/1234/money_transfer?user=4567;amount=1 > >> However that is not CRUD-like, nor a direct mapping of DBIC functionality > >> to > >> REST) > > > > The solution suggested in "Restful Web Services" is to POST to a "factory" > > resource which creates you with a transaction resource. e.g. "POST > > /transactions/account-transfer" returns "Location: > > /transactions/account-transfer/11a5", where the 11a5 is a unique > > transaction identifier. > > > > Then "PUT /transactions/account-transfer/11a5/accounts/checking/11", where > > 11 is the account identifier. The body carries the transaction details, in > > the example the balances are adjusted absolutely, i.e. "balance=150". A > > similar PUT is sent for the other account. > > > > Once the required components of the transaction have been PUT it is > > possible to rollback by DELETEing the transaction resource or commit it by > > putting "committed=true" to the resource. > > > > While seeming a bit fiddly, it does keep the state on the client and allows > > the client to make (at least some of) the commit / rollback decision rather > > than (only) the server. > > I've read parts of RESTful Web Services, but not that bit.. I'll have to go > back and look. > > I wonder how one goes about implementing such a transaction on the server > side.. One would not want to lock DB rows indefinitely, waiting for the > client > to finally complete the transaction. But if one just recorded the queries and > then executed them all (internally) at the end, then other risks exist, eg: > > $id = POST transaction > $amount = GET /user/1/account_balance > $amount2 = GET /user/2/account_balance > PUT /user/1/account_balance/$amount-1 > PUT /user/2/account_balance/$amount+1 > PUT transaction/$id?completed
How about: $id = POST transaction PUT /transaction/$id/payer/1 PUT /transaction/$id/receiver/2 PUT /transaction/$id/amount/1 PUT /transaction/$id?completed or even $id = POST transaction PUT /transaction/$id?payer=1;receiver=2;amount=1 PUT /transaction/$id?completed And - yeah - looks like we have differnet goals. But I'll watch your project proceeding :) -- Zbigniew Lukasiak http://brudnopis.blogspot.com/ _______________________________________________ List: [email protected] Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/[email protected]/ Dev site: http://dev.catalyst.perl.org/
