Hugh Winkler holding forth on computing and the Web

Monday, April 24, 2006

GData Optimistic concurrency

Google Data APIs beat Atompub to the punch and stamped legitimacy on REST. I hope Atompub will end up looking as nearly like GData as possible.

Of note: this is a Hi-Rest API, and now, we can safely say, it's the way the web actually works. Not just the way some very dedicated people aspire for the web to work.

So enough rejoicing. Let's begin analyzing GData to death.

First technical question: optimistic concurrency: What's wrong with plain old HTTP if-unmodified-since/if-match? That's how you guard against concurrent updates in HTTP right? Why invent a new protocol for that?

Thursday, April 06, 2006

SOAP+REST: Why?

mnot declares
I’m a little confused by Mark Baker’s stance regarding SOAP; he seems to encourage the Web services world to use SOAP on top of HTTP in a fashion compatible with HTTP.


MarkB responds he's offering a face-saving out for SOAP vendors. Is that the best reason? I can't think of one reason to wrap the messages I traffic in, in a SOAP envelope. What are the use cases for RESTful SOAP, please?

Slightly More Complex List Extensions

Using the MS Simple List Extensions for RSS and Atom, you can really make a "feed" be anything you want it to be. Anything you can put between the angle brackets of a <cf:treatAs> tag, you can represent in a feed. I call it SMCLE (Slightly More Complex List Extensions).

Here is how it will work:

We'll define several new values for <cf:treatAs> element. Currently the only defined value is "list". Now we will have:
<cf:treatAs>Bag</cf:treatAs> : the items form an unordered collection.
<cf:treatAs>Queue</cf:treatAs> : the items form a fifo queue.
<cf:treatAs>Stack</cf:treatAs> : the items form a lifo queue.
<cf:treatAs>CircularQueue</cf:treatAs> : when you get to the end of the collection, start over again at the top.
<cf:treatAs>OneBigString</cf:treatAs> : the items aren't items at all, in the RSS/Atom sense. The content of items really should be concatenated to form one big string.

Additionally, we'll allow extension namespaces so you can define your own "treatAs" values, e.g.:


<cf:treatAs ns="http://my.example.com/smcle">JavaScriptStatements</cf:treatAs>



Now, I know your aggregator is going to suck if it can't process all these variations correctly. Not to worry: the MS Feeds API will handle it all for you! In fact, the MS Feeds API will pretty much become the definition of a feed. If it doesn't work with the API, you don't need it!

Wednesday, April 05, 2006

Simple List Extensions: Invidious?

The Microsoft Simple List Extensions for RSS + Atom seem like a great idea. You declare attributes for your entries -- like Artist, Date Added, Price, Sales Rank -- and then set the attribute values on each entry. It's a tiny little schema language, with a type system. IE7 can then sort and filter the entries based on those attribute values.

The problem is that once you have that capability, you come to rely on it. If your site has a thousand entries, you can serve it up as a single feed with attributes allowing the client to filter. But you'd organize your site differently if clients didn't have that capability. So, for feed readers not supporting SLE, you'd want to break up your site into several feeds, maybe one for each Artist.

I'm sure every feed reader will have to support these extensions. Otherwise they would appear to suck on feeds that rely on SLE.

Thursday, March 30, 2006

IE7 Transforms Atom to RSS 2

I put a little mileage on IE7 feeds today.

First this Wellstorm Atom feed. Of note: a) it validates on Feed validator; b) it uses an extension namespace; c) it specifies a CSS stylesheet.

I've pasted in the relevant files below.

Observations:

IE7 uses its own stylesheet, ignoring mine. That's ok I guess; it's a smart client, so it should be styling to suit its own purposes.

Before you subscribe, View Source: It displays the Atom xml content.

After you subscribe, View Source: IE7 has transformed the Atom to RSS 2.0.

Unfortunately, within IE7 you can never again view the original atom file! You can't enter the URL and View Source... it always shows it transformed to RSS. Weird.

Here is the Atom feed:


<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet href="http://www.hughw.net:8080/witsml/styles/atom.css" type="text/css"?>
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:wixp="http://www.wixp.org/ns/atom">
<id>http://www.hughw.net:8080/witsml/atom/Default%20Repository/!well</id>

<title>WITSML Repository</title>

<updated>2006-03-17T14:01:14.935-06:00</updated>

<link rel="self" href="http://www.hughw.net:8080/witsml/atom/Default%20Repository/!well"/>

<entry>
<id>http://www.hughw.net:8080/witsml/atom/Default%20Repository/well.W-12</id>
<title>6507/7-A-42</title>
<link href="http://www.hughw.net:8080/witsml/atom/Default%20Repository/well.W-12.rby" rel="http://www.wixp.org/rel/contains"/>
<updated>2001-05-31T08:15:00.000000+00:00</updated>
<published>2001-04-30T08:15:00.000000+00:00</published>

<author><name>John Smith</name></author>
<wixp:ObjectType>well</wixp:ObjectType>
<wixp:LastModified>2006-03-17T14:01:14.935-06:00</wixp:LastModified>
<wixp:Name>6507/7-A-42</wixp:Name>
<wixp:uidWell>W-12</wixp:uidWell>
<wixp:nameSource>John Smith</wixp:nameSource>

<wixp:dTimStamp>2001-05-31T08:15:00.000000+00:00</wixp:dTimStamp>
<wixp:dTimCreation>2001-04-30T08:15:00.000000+00:00</wixp:dTimCreation>
<wixp:dTimLastChange>2001-05-31T08:15:00.000000+00:00</wixp:dTimLastChange>
<wixp:itemState>Plan</wixp:itemState>
<wixp:comments>These are the comments associated with the Well data object.</wixp:comments>
<summary type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><a href="http://www.hughw.net:8080/witsml/atom/Default%20Repository/well.W-12">well 6507/7-A-42</a> <a href="http://www.hughw.net:8080/witsml/atom/Default%20Repository/well.W-12.rby">[contents]</a></div></summary>

<content src="http://www.hughw.net:8080/witsml/atom/Default%20Repository/well.W-12" type="application/x.witsml+xml"/>
</entry>
</feed>

Here is the IE7 persisted version:

<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:cf="http://www.microsoft.com/schemas/rss/core/2005">
<channel>
<guid isPermaLink="false">http://www.hughw.net:8080/witsml/atom/Default%20Repository/!well</guid>
<title cf:type="text">WITSML Repository</title>
<pubDate>Fri, 17 Mar 2006 14:01:14 GMT</pubDate>
<atom:link href="http://www.hughw.net:8080/witsml/atom/Default%20Repository/!well"
rel="self"/>
<item>
<guid isPermaLink="false"
>http://www.hughw.net:8080/witsml/atom/Default%20Repository/well.W-12</guid>
<title xmlns:cf="http://www.microsoft.com/schemas/rss/core/2005" cf:type="text"
>6507/7-A-42</title>
<atom:link xmlns:atom="http://www.w3.org/2005/Atom"
href="http://www.hughw.net:8080/witsml/atom/Default%20Repository/well.W-12.rby"
rel="http://www.wixp.org/rel/contains"/>
<pubDate>Thu, 31 May 2001 08:15:00 GMT</pubDate>
<atom:published xmlns:atom="http://www.w3.org/2005/Atom">Mon, 30 Apr 2001 08:15:00 GMT</atom:published>
<author>John Smith</author>
<atom:author xmlns:atom="http://www.w3.org/2005/Atom">
<atom:name>John Smith</atom:name>
</atom:author>
<wixp:ObjectType xmlns="http://www.w3.org/2005/Atom"
xmlns:wixp="http://www.wixp.org/ns/atom">well</wixp:ObjectType>
<wixp:LastModified xmlns="http://www.w3.org/2005/Atom"
xmlns:wixp="http://www.wixp.org/ns/atom">2006-03-17T14:01:14.935-06:00</wixp:LastModified>
<wixp:Name xmlns="http://www.w3.org/2005/Atom" xmlns:wixp="http://www.wixp.org/ns/atom"
>6507/7-A-42</wixp:Name>
<wixp:uidWell xmlns="http://www.w3.org/2005/Atom"
xmlns:wixp="http://www.wixp.org/ns/atom">W-12</wixp:uidWell>
<wixp:nameSource xmlns="http://www.w3.org/2005/Atom"
xmlns:wixp="http://www.wixp.org/ns/atom">John Smith</wixp:nameSource>
<wixp:dTimStamp xmlns="http://www.w3.org/2005/Atom"
xmlns:wixp="http://www.wixp.org/ns/atom">2001-05-31T08:15:00.000000+00:00</wixp:dTimStamp>
<wixp:dTimCreation xmlns="http://www.w3.org/2005/Atom"
xmlns:wixp="http://www.wixp.org/ns/atom">2001-04-30T08:15:00.000000+00:00</wixp:dTimCreation>
<wixp:dTimLastChange xmlns="http://www.w3.org/2005/Atom"
xmlns:wixp="http://www.wixp.org/ns/atom">2001-05-31T08:15:00.000000+00:00</wixp:dTimLastChange>
<wixp:itemState xmlns="http://www.w3.org/2005/Atom"
xmlns:wixp="http://www.wixp.org/ns/atom">Plan</wixp:itemState>
<wixp:comments xmlns="http://www.w3.org/2005/Atom"
xmlns:wixp="http://www.wixp.org/ns/atom">These are the comments associated with the
Well data object.</wixp:comments>
<description xmlns:cf="http://www.microsoft.com/schemas/rss/core/2005" cf:type="html"
><div><a href="http://www.hughw.net:8080/witsml/atom/Default
Repository/well.W-12">well 6507/7-A-42</a> <a
href="http://www.hughw.net:8080/witsml/atom/Default
Repository/well.W-12.rby">[contents]</a></div></description>
<content src="http://www.hughw.net:8080/witsml/atom/Default%20Repository/well.W-12"
type="application/x.witsml+xml" xmlns="http://www.w3.org/2005/Atom"
xmlns:wixp="http://www.wixp.org/ns/atom"/>
<cf:id>0</cf:id>
<cf:read>true</cf:read>
</item>
</channel>
</rss>

Monday, March 27, 2006

Lisp for Entrepreneurs

Yet another Lisp is for Entrepreneurs link -- this one from Bill Clementson. Programming languages are converging on Lisp, so I'm bypassing the deep dive on Ruby...

I've gone deep on Lisp recently and I have to tell you: maybe I'm not smart enough to be a Lisp programmer, at least soon enough. I've written a functioning, and reasonably complex, program (a Gibbs sampler for a Bayesian network) but I can hardly read the thing. It's all (car(cdr(assoc('xxx ...)))) ...that design is nobody's fault but my own, but it's just the path of least resistance as I'm writing the thing. I have begun to see a few glimmers of possibilities I don't have in other languages. I've written a macro, and I get it. I've passed lambdas to functions. This code is a a lot terser than a Java version I wrote years ago. Terse is good, right? But I have to comment the code more extensively because it's not really "self describing."

Maybe I'm the sort of weak-natured guy who needs an early-binding language enforcing the discipline up front. 'Cause I have to admit, strong typing makes me write better programs. It's a character flaw.

Wednesday, March 22, 2006

Microcontent Three-Way Processses

We're all going to have to package our services as microcontent (via Sean McGrath). For those of us in the business of delivering "two-way" data services, our webapps will wither. Good!

Now we have to figure out how to get paid. I can deliver some critical information to you via Atom or RSS. And you have some client subscribing, consuming, and processing that data on your behalf. I need to get paid by subscription, or by the piece. I'll no longer have a webapp where you subscribe or agree to purchase single items, and where I meter your consumption. Aggregators, and successor services like them, will have to do that. So we need extensions to APP to compose three-way transactions.

So you will initiate a subscription via your aggregating service. I'm not neccessarily talking about a feed aggregator; this might be some specialized service in a vertical, like stock quotes. It will collect your personal and payment information. It will contact me to subscribe you. It will send me your PayPal, or whatever, payment authorization. I will respond with approval or denial. When retrieving information on your behalf, your aggregator definitely has to tell me you are retrieving that information, so I can authorize it. Contrast to current practice: aggregators retrieve a feed on behalf of hundreds of anonymous users. And we have to address the issue of whether I trust the aggregator service to tell me the truth, or whether we can design protocols preventing it paying for one subscription when it has sold 20.

To make that happen, we'll need a microcontent business process specification that can compose three-way transactions. And it has to be as simple and transparent as RSS and Atom. I'm not talking about BPSS, although there's a lot to be learned there.

Spooky Rojo Mojo

Alerted by Mark's post that he switched to Rojo, I just now signed up to give it a try. After going through the wizard, I land on my new home feeds page. And my very first "Rojo Feed Recommendation" is: Mark's other blog, Integrate This. And no, I haven't imported my feeds from Bloglines yet!

Thursday, March 16, 2006

URIs are opaque, except when they're not

Roy jumps in to clarify the law about URI opaqueness:

The key is that the server is free to tell the client that there does exist structure in a given URI-space, and then the client is free to make use of that knowledge in future requests. That is how server-side imagemaps worked -- HTML says that the URI is structured such that appending "?X,Y" to that URI, where X and Y are non-negative integers, corresponds to points on a map that can respond to future GET requests.

Thus, one way for the server to tell the client that a given URI is structured is to provide the URI in a standard element of a standard media type that has been defined as such. Another is to include the URI in a response header field.


I may be having my own, belated moment of total, violent, zen clarity.

Saturday, March 04, 2006

Patterns Problem

Peter Seibel's book has a nice analysis of the "patterns problem":

The reason both these functions start the same way is because they're both test functions. The duplication arises because, at the moment, test function is only half an abstraction. The abstraction exists in your mind, but in the code there's no way to express "this is a test function" other than to write code that follows a particular pattern.

Unfortunately, partial abstractions are a crummy tool for building software. Because a half abstraction is expressed in code by a manifestation of the pattern, you're guaranteed to have massive code duplication with all the normal bad consequences that implies for maintainability. More subtly, because the abstraction exists only in the minds of programmers, there's no mechanism to make sure different programmers (or even the same programmer working at different times) actually understand the abstraction the same way. To make a complete abstraction, you need a way to express "this is a test function" and have all the code required by the pattern be generated for you. In other words, you need a macro.


Lisp, again.