Category “commentary”

Units of Work

Friday, 20 March, 2009

In regard to cross-resource transactions, I’m a member of the camp that wonders whether distributed transactions are strictly necessary in the REST/HTTP world; indeed I wonder whether they represent a design failure in modeling the granularity of your resources.

That said, we don’t live in a perfect world — and even if I can’t envisage why a properly designed RESTful application might require access to a distributed transaction, I can certainly envisage the environment where such an application might evolve. I’ve worked in a few of them. Places where interdepartmental barriers are as solid as the Great Wall; bastions of archaic technology where “one might provide a pseudo-RESTful interface, but one certainly won’t be re-architecting one’s legacy system in the buzzword language of the day”.

But, I think there’s a certain amount of smoke and mirrors in the JBossTS article “Transactional support for JAX RS based applications“:

Certainly it is worth pointing out that if a system cannot be made reliable then it can be of only limited utility. That said it is a worthwhile exercise to show how a REST based system can be made reliable.

Lack of distributed transactions would hardly seem to make a REST based system “unreliable” and, as a consequence, of “only limited utility”. Imagine a hotel booking facility — perhaps a booking resource, which internally might be constructed from a number of components, all governed (again internally) by transaction demarcation. Does the fact that the booking resource is coarse-grained and does not require an external transaction make it less reliable than a number of fine-grained resources which do? On the contrary. The latter sounds more like a WS-* api than a RESTful architecture, nothing to do with reliability.

So… hopefully it’s obvious I think it’s a bad idea. But if I were to write such an API, I think the 8-year old spec mentioned in the article falls short of the mark. Here’s my first-cut attempt at an alternative (which I still think falls a bit short of the mark, but is possibly an improvement):

Resource: tc
Method URL Content Description Statuses
GET /tc Returns HTML containing a summary of all transactions (status), plus an href to the transaction detail 200 – ok
/tc/{txid} Returns HTML containing detail for the transaction with id {txid}, including the status and a list of hrefs to the each of the participants. For example:


<html>
<body>
	<dl>
		<dt>Transaction ID</dt>
			<dd id="transaction-id">12345a</dd>
		<dt>Status</dt>
			<dd id="transaction-status">ACTIVE</dd>
		<dt>Timeout</dt>
			<dd id="transaction-timeout">5000</dd>
	</dl>
	<ul id="participants">
		<li>
			<a href="/tc/12345a/participants/1">
				Participant 1
			</a>
		</li>
		<li>
			<a href="/tc/12345a/participants/2">
				Order
			</a>
		</li>
	<ul>
</body>
</html>
200 – ok

404 – if txid is not found
409 – if the transaction has been deleted
/tc?status={status-type} Return HTML containing a summary of transactions with a specific status, with href to the transaction detail
For example: /tc?status=recovering or /tc?status=active
200 – ok
/tc/{txid}/participants Return a list of participants in the transaction (list of hrefs) 200 – ok
404 – if the transaction does not exist
/tc/{txid}/partipants/{rec-coord-id} Return HTML containing the detail of a participant. For example:


<html>
<title>Participant #2</title>
<body>
<dl>
    <dt>ID</dt>
        <dd>2</dd>
    <dt>Name</dt>
        <dd>Order</dd>
    <dt>URL</dt>
        <dd>
            <a href="http://internal.mydomain.com/someresource/123">Order</a>
        </dd>
</dl>
</body>
</html>
200 – ok
404 – if the transaction or participant does not exist
POST /tc [timeout={timeout}] Start a transaction (with default timeout) returning the url /tc/{txid} — which is deleted after the timeout or after completion (any HTTP method relating to {txid} thereafter returns 404). Use timeout={timeout} to override the default timeout period. 201 – created
DELETE /tc/{txid} Rollback and stop a transaction 204 – ok
404 – if the transaction does not exist
/tc/{txid}?commit Commit and stop a transaction 204 – ok
404 – if the transaction does not exist
POST /tc/{txid}/participants url={url}&[name={name}] Enlist {url} in the transaction, returning a unique resource for that participant of the form /tc/{txid}/participants/{rec-coord-id}. If name exists, record against the participant detail 201 – created
404 – if the transaction does not exist
PUT /tc/{txid}/participants/{rec-coord-id} url={url} Replace the participant url 200 – ok
404 – if the transaction or participant does not exist

The resource identified by a participant URL will have the following semantics:

Method URL Content Description Statuses
PUT URL/tx/{rec-coord-id} action=prepare The participant prepares any work done in the context of the transaction. The Warning header will contain additional info about the state of the prepare (either readonly, or notok). 200 – ok
200 – ok (+ Warning: readonly)
200 – ok (+ Warning: notok)
404 – participant has rolled back
action=commit The participant commits any work done in the context of the transaction. 200 – ok
200 – ok (+ Warning: heuristic)
404 – participant has rolled back
action=rollback The participant commits any work done in the context of the transaction. 200 – ok
200 – ok (+ Warning: heuristic)
404 – participant has already rolled back

Basic usage might look something like the following:

1. Create a new transaction resource
POST /tc
Host: somedomain.com

timeout=5000
HTTP/1.1 201 Created
Connection: close
Date: Thu, 19 Mar 2009 21:01:56 GMT
Location: http://somedomain.com/tc/10a23v991
X-Powered-By: TransactionServer/0.1
2. Create a new resource of some kind (notify the resource that it will operate with a distributed transaction)
POST /res1?tx
Host: internaldept1.somedomain.com

<xml>some xml describing the resource</xml>
HTTP1.1 201 Created
Connection: close
Date: Thu, 19 Mar 2009 21:01:56 GMT
Location: http://internaldept1.somedomain.com/res1/100
3. Update another resource (again notify that it will be operating within a transaction)
PUT /res2/somename?tx
Host: internaldept2.somedomain.com

<xml>some xml describing the update,
perhaps including a reference to the previously
created resource</xml>
HTTP1.1 200 Ok
Connection: close
Date: Thu, 19 Mar 2009 21:01:56 GMT
Location: http://internaldept2.somedomain.com/res2/somename
4. Enlist the url for each resource in the transaction
POST /tc/10a23v991/participants
Host: somedomain.com

name=resource1&url=http://internaldept1.somedomain.com/res1/100
HTTP/1.1 201 Created
Connection: close
Date: Thu, 19 Mar 2009 21:01:56 GMT
Location: http://somedomain.com/tc/10a23v991/participants/a01abgv21
X-Powered-By: TransactionServer/0.1
POST /tc/10a23v991/participants
Host: somedomain.com

name=resource2&url=http://internaldept2.somedomain.com/res2/somename
HTTP/1.1 201 Created
Connection: close
Date: Thu, 19 Mar 2009 21:01:56 GMT
Location: http://somedomain.com/tc/10a23v991/participants/a01abgv22
X-Powered-By: TransactionServer/0.1
5. Commit the transaction
DELETE /tc/10a23v991?action=commit
Host: somedomain.com
HTTP/1.1 204 Committed and deleted
Connection: close
Date: Thu, 19 Mar 2009 21:01:56 GMT
X-Powered-By: TransactionServer/0.1
6. ‘Behind the scenes’, the commit results in the following (2-phase commit at this point)…
PUT /res1/100/tx/a01abgv21
Host: internaldept1.somedomain.com

action=prepare
PUT /res2/somename/tx/a01abgv22
Host: internaldept2.somedomain.com

action=prepare

and

PUT /res1/100/tx/a01abgv21
Host: internaldept1.somedomain.com

action=commit
PUT /res2/somename/tx/a01abgv22
Host: internaldept2.somedomain.com

action=commit

Flaws?

Monday, 2 March, 2009

Last September, I posted about a somewhat odd exchange between myself and the developer of a competing shopping cart plugin, over a troll whom, in the end, wound up attacking both plugins.

Since then, I’ve come across a few negative comments about YAK on various forums — interestingly, in none of these cases has the poster actually contacted me. All too similar to the original troll.

The usual process, when there’s been a real issue with YAK, is that someone lets me know, I fix said issue (or otherwise try to resolve), and release a new version. So far, I’ve only been notified about one legitimate hole in the code (quickly fixed), and (at least, as far as I can recall) haven’t left any major flaws outstanding for great lengths of time. So I haven’t been enormously worried about the odd malcontent.

That said, I occasionally google to see what’s being said out there, and came across the following gem (from the aforementioned plugin developer).

If you want to throw up an image with a price in a page or a post then by all means use YAK. But if you want the real deal then [competing-plugin] is built on years of e-Commerce knowledge and has plenty of important features for people wanting to SELL Online – such as the ability to interface with many payment gateways, the ability to interface with shipping companies, and much much more

(Note: I’ve removed the name of the plugin because I’ve thus far tried to avoid actually naming the individual involved).

This was posted sometime after May last year, but I do feel the need to make a couple of comments, even though it’s almost a year old:

1. What’s your definition of important feature? Get a group of users together, and I guarantee they won’t come up with the same list.
2. YAK now supports a number of payment gateways (PayPal standard, PayPal Pro, Authorize.net and basic Google Checkout integration)
3. Okay, it doesn’t directly interface with shipping companies — but the shipping calculation is relatively flexible, and I’m always open to suggestions.
4. YAK as a project has now been actively (if intermittently) developed for 3 years. So I’d say it also fulfills the assertion: “built on years of e-Commerce knowledge”. :-P

UPDATE: here’s another interesting comment (by someone called Mccormicky) which I came across after posting this:

Yak cart is another you might consider if you don’t mind repairing tables in mysql. I did it and I am no expert.
Yak is not that supported either-there isn’t even an onsite tutorial for setting it up and the readme contains nothing about where to put the hooks! I was amazed.

It looks like fairly obvious trolling, given that (at the time it was posted) there was certainly a basic tutorial for YAK setup, and at the time I don’t recall being contacted about any “table repair” problems. Weird.

What is it with shoes lately?

Sunday, 21 December, 2008

First of all a journalist throwing his shoe at Dubyah, then shoe company throwing their weight at a small NZ online retailer:

British (shoe design [sic]) company, Jimmy Choo has told the north of Auckland gift seller website, Kookychoo.com, it must agree to give up its name by Tuesday, or face a lawsuit.

I have to admit, I find this kind of thing (the latter rather than the former), really annoying. Undoubtedly some kind of Freudian “David versus Goliath” kind of thing.

I have no problem with a company trying to protect its brand, but I have a big problem with the manner and terms by which they do so. In any case, let’s face it, the only reason one might associate the brand “Kookychoo” with “Jimmy Choo” is now because of this case.

ARTS, or the lack thereof

Friday, 7 November, 2008

I’ve been looking at providing a basic xml product feed through YAK (needed for some rather esoteric customer requirements) — at the experimental stage, rather than a feature that will actually make it into development or release. I cast around for some standardised XML formats, and hazy recollection (thanks TOGAF) popped ARTS into my head. ARTS is the Association for Retail Technology Standards (developed by the National Retail Federation — NRF’s byline is “The Voice of Retail Worldwide”. Not to be petty, but wouldn’t International Retail Federation be a better name if you’re talking global?) and they publish a bunch of schemas which I figured may be useful — particularly their inventory schema. Why come up with my own format, when I can use the work of someone else?

Unless, of course, the work of “someone else” amounts to a half-meg schema file.

Now, my spider senses start tingling if I come across a single schema file that’s over a few 100 kilobytes, but Netbeans gets it’s knickers in a right proper twist if you try to generate sample xml from this epic monstrosity. 289MB generated before I managed to kill the process.

And oh, what an xml. I don’t think separation of concerns was a primary, secondary or even tertiary thought for whoever sat down with tool in hand to design this particular ‘standard’. If a simple type named ActionCommonDataTypeCodesEnumeration isn’t worrying enough, the fact that it contains terms such as Begin, Cancel, Complete, Create, Delete, Dispatch, Lookup, Initiate, Instruction, Information, PartialCancel, PartialComplete, Read, Request, Update, and so on, hurts the back of my brain.
Let’s not get started on PriceCommonData, UnitPriceCommonData, and the myriad other CommonDatas littered through the document. Ack. Aching brain.

Okay, yes, I’m not the target audience, and I haven’t paid the US$149 for the documentation, so I may be reading more into the schema than I probably should, but if I look at it through even slightly REST-tinted glasses, it frankly gives me the heebie-jeebies.

Suffice it to say that I will probably not be using ARTS’ inventory.xsd for my, much simpler, requirements. I may indeed roll my own, but happy to entertain suggestions if someone has a better idea.

Quote of the Day…

Tuesday, 21 October, 2008

Quote of the Day goes to Roy Fielding for the excellent:

That is RPC. It screams RPC. There is so much coupling on display that it should be given an X rating

Word on the Mac is a Mess

Friday, 17 October, 2008

Word on the Mac is a mess, and I don’t like Excel much either. The lack of VBA macro support means it’s useless for the purpose I originally bought it for — teach me to not double-check the specs before I buy.

Worse yet, Word appears to no longer support Thai language — meaning it’s not fit-for-purpose for my wife either. Unfortunately, we left the Office 2003 disk in storage, back in NZ, so we can’t rollback to the version of Office that did support Thai language.

Exactly why is Office such a cash cow for Microsoft? Because of muppets like me, obviously.

On Trolls and Other Nasty Beasts

Sunday, 21 September, 2008

A few months ago, the author of a competing plugin (to my own rather more modest efforts), contacted me about a troll he was having trouble with. Said troll was posting negative messages about the competition on various forums, and his theory was that the guy is my supporter.

Somewhat irritating, was the fact he claimed to have found connections between us. Quite how he managed to find a connection I don’t know — given that there were/are none — but more galling was the subsequent request that I post messages to that effect, on all the forums where this muppet had been posting. Needless to say, I was somewhat less than agreeable, and I suspect that my refusal cemented whatever paranoid delusions of persecution he had conjured.

I only bring this up now, because YAK has suddenly become the target of that self-same troll. Or at least, I’m guessing it’s the same twit (given the similarity of name). This time ridiculously claiming that my plugin has somehow opened a gaping security hole in WordPress’s administration panel. Laughable.

I suggest that rather than YAK causing the problem, it’ll be the fact that this individual has a few too many brain-cells short of a functional cranium, and that “password” is rather too simple an administration password.
On the positive side, it does hopefully prove that the troll has nothing to do with me, and is obviously a sad git with far too much spare time on his hands.

UPDATE: just to be thorough, I’ve double-checked some of the access points in YAK where there might’ve been potential for a security hole, and I can’t see anything that might compromise WP’s security. So I return to my earlier description of the poster: a muppet.

Metro’s best restaurants

Sunday, 24 August, 2008

Can’t say I’m that impressed by Metro’s selection of the best Auckland restaurants. At least not the Thai choice. Thai Friends has the benefit of a nice view of the Domain, but the last time we went (a few months before we left NZ) the food was just so-so. The 2007 winner (Red Elephant) was an order of magnitude better. It even impressed my wife, which, when it comes to Thai restaurants, is extremely difficult to do.

Transpose Red Elephant’s menu and chefs to the Thai Friends location and you’d have the perfect restaurant. As it is, I’d rather put up with the crappy view of Khyber Pass and the motorway, and enjoy the steamed snapper and flaming chicken.

Interestingly, I have yet to find a Thai restaurant in London which comes even close to Red Elephant. The closest would be (coincidentally) Blue Elephant in Fulham — but that has variety in its favour rather than quality.

Is Age a Barrier to Learning?

Friday, 22 August, 2008

Is age a barrier to learning?

I don’t think so. I’m attempting to follow the pragmatic creed of learning a new programming language a year (well, laziness will probably turn it into every 2 years, but that’s nothing to do with age), and I think my head is in a better place now, to do so, than it was 10 years ago. Certainly my mother doesn’t think age is any barrier — she started learning Spanish in her late 20s (I seem to recall), and began Italian well into her 50s.

I could probably come up with numerous other examples at a push.

So the fact that the British High Commission in Thailand has just rejected my sister-in-law’s student visa because of her age (early 30s) smacks of excuse, rather than legitimate reason (in which case, why didn’t they tell us the real reason for the rejection?)
Despite the fact we pre-paid for the course, provided evidence of income, accommodation, etc, etc, etc — all the masses of paperwork you need to provide when sponsoring a visa application — it appears that ageism is rife within the Home Office.

Disappointing.

Cloud Camp

Thursday, 17 July, 2008

Cloud Camp London:

First talk, good. Last talk, good. Stuff in between… meh.

Highlights of the evening: catching up with Ben. And, after 7 years, finally meeting Alan (the last talk!) in person…

…even if it was only for a few minutes. ;-)