I’ve had a couple of conversations recently – one online and one off – that both centered around an important aspect of distributed computing that is often overlooked: the role of users in determining message semantics. When we write and deploy software, either client or server, it is easily forgotten that this software has been deployed on behalf of some user, either us, our employer, a customer, etc.. For example, Web browsers act on behalf of the users sitting right in front of them, while Web servers act on behalf of the publishers. We even have a special name for this software – though only typically used to refer to clients – user agents. The name drives home the point that they do our bidding alone. When a user initiates an action which requires messages to be sent, then the message needs to reflect the intent of the user. For example (the subject of the aforementioned online discussion) when a user clicks a link in a browser it is with the intent of dereferencing that link, an action which is by definition safe. Therefore, any message sent as a result of a clicked link must be a safe message, otherwise it would be misrepresenting the user. Another scenario where this issue pops up is in the context of application/session state. My friend Bob Haugen and I recently discussed whether the canonical Web shopping cart was stateful or stateless. After a few back-and-forths, we had boiled down the discussion – I thought it was stateful, Bob wasn’t sure – to this same issue. Bob thought that the POST message that gets sent in response to a “purchase” action by the user had the meaning “Purchase what’s in that shopping cart”. And if that was the case, he’d be right, it would be stateless. But my point was that the message can’t mean that because pretty much every user wants to be explicit about what they’re purchasing, and so include the details about the purchase – items, quantity, price, shipping terms, etc.. – in the message sent to the server. In explaining my position, I pointed out that pretty much every shopping cart service I’ve ever used notifies users if prices changes between the time the item was added to the shopping cart, and when the purchase is initiated. This is done because the service understands that it is the user’s intent to be specific about what they’re buying, it’s just that the technology in use – a Web browser – doesn’t easily permit that kind of information to be maintained on the client so that it can be sent over in the POST message. Food for thought, I hope.
Trackback

2 comments until now

  1. Your description of the “shopping cart problem” reminds me of the discussions on batching requests that have recently come up. To some extent, you could imagine a shopping cart as a set of resources that you’ve GETted, and that checking out, you’d like to POST to all of them at once. That’s not quite right of course, you’d want to represent the items as a capability of being purchased, and the POST to them executes it, or something. But anyway, this is a great example of the problems with batching, if you think about the real life situation of a “price change” or other status change of the item. A customer might want to just remove that item from the cart, they may decide to not buy anything, they may decide to complain to the store management.

    So, actually, I think a web browser COULD handle this case fairly easily, but it actually greatly complicates the ensuing understanding of the client / server interface, which is probably not a good thing.

  2. So if the shopping cart is stateful, and I agree, does that mean then that shopping carts violate RESTful architecture and are indeed “bad” from a REST perspective?

    I can envision a shopping cart where the client holds only everything needed by an order and then submits it all, but most carts don’t take that approach.

    And that approach wouldn’t work well when and if the same pattern was used for an extremely large “order”, right? To say nothing of transactions where a POST request returns a new transaction ID and subsequent PUTs add actions to the transaction with a final PUT to complete the transaction?

    It’s been 5+ years since you posted this, any updated thoughts?

Add your comment now