<M <Y
Y> M>

[Comments] (3) Involuntary NaNoWriMo: Several people I know are doing NaNoWriMo, including some of Sumana's coworkers. Sumana was tempted to do it but I told her she has too much else she has to do. I'm tempted to do it as well, but I already have a book deadline at the end of the month. So it's like I'm doing it already but not getting credit.

: What's New at the Internet Archive. Subscribed!

Milestones Around My Neck: As of today my book is 150 pages long (public announcement coming soon, honestly, along with lots of me complaining about how things should be other than they are; which, though cranky, will provide interesting content on this weblog). Also, I finished my story today, and it did in fact turn into a novella. Now working on it with Brendan; it's called "Vanilla".

[Comments] (1) Disturbing Slash Concepts: CJ from Reginald Perrin and CJ from The West Wing.

[Comments] (5) REST Web Services: I'm writing a new book and it's called REST Web Services. It will be be the only book of its kind, and everyone should buy it who writes computer programs that work over the web.

There are lots of books about Big Web Services: complex distributed-object systems that reproduce the mechanics of method calls over HTTP. The problem is 1) these systems are way too big for what they do, and 2) they're on the web but they aren't of the web. They don't use any of the web's features, or interact with anything else on the web. They just use HTTP as a transport protocol. They could just as easily run over TCP and get better performance.

These un-weblike systems were able to take the name "Web Services" away from the competition because the competition is... the web. Just writing programs that interact with the web. Sounds pretty sketchy! The web may be all right as a platform for serving movies, or selling books, or trading stocks, or democratizing publishing, or coordinating huge volunteer projects, or searching much of the information currently in existence, but there's no way it's up to the task of managing Accounts Payable! For that you need... Web Services!

As Big Web Services gathered steam, the pro-web forces rallied behind the banner of REST: a name for the design philosophy that made the human-visible web so successful. They preached simplicity, addressability, statelessness and the uniform interface of HTTP. They also got into lots of heated arguments about what REST really meant.

Some organizations created services that claimed to be RESTful, and others critiqued those services and said they weren't RESTful really, and is "RESTful" even a word? Meanwhile the world's programmers started finding options in their IDEs that generated code for Big Web Service clients and servers, so they wouldn't have to do so much programming.

I got the idea for a REST book when I started seriously trying to figure out what was and wasn't REST. I noticed that though certain best practices showed up repeatedly in REST folklore, they never really progressed beyond that point. I decided to write a book that would set down the folklore and hopefully create some new canon, some common ground. I got Sam Ruby to agree to do the hard parts. And when I started work on the book I discovered a basic rule of thumb, a framing device that really focuses on what's important about REST, and makes it easy to tell what's RESTful and what's not.

We call this framing device the Resource-Oriented Architecture (we're not the first, but the other uses are compatible with ours), and I'm going to be writing about it a lot more in NYCB. It's too good to keep hidden in a book along with a bunch of implementation details.

Some people might say, "Leonard, why are you guys even writing this book? There already are lots of books about the web, and REST is just the web, right? That's the whole point! We wrote those books back in the 90s."

To them I say: "Some people, think about Ajax for a bit. Ajax, as a technology, is only about two years old, but it's composed entirely of technologies that are much older, like Javascript and XMLHttpRequest and the browser DOM. So why are there all these books about Ajax? (Including Christian Gross's Ajax and REST Recipes, coming out later this month and seemingly the only other book to mention REST in the title.) Why does Ajax excite people when DHTML was a big yawn? Because Ajax is a way of framing these old technologies so that people can do awesome things.

"There's nothing on the market that explains what REST really means and how to make it work for you. Nothing about programming the web in a way that's more structured than screen-scraping without falling into the pit of Big Web Services. This is a way of framing preexisting technologies that lets people do awesome things."

Then I add, "Speaking of Ajax, did you know that an Ajax application is basically a REST web service client that runs in your web browser? That's why Christian Gross's book is called what it is, and that's just one of the amazing reality-twisting facts you'll learn from my new book, Jon." Because I'm talking to Jon Stewart! I'm on The Daily Show, plugging my new REST book! It's a dream come true! But wait--I'm not actually on The Daily Show! I'm just on a clip from The Daily Show that someone uploaded to YouTube! And now someone is sending a DELETE request to my URI! I can see the Authorization request header, its value is "DMCA Takedown Notice", and nooooooooooo

Then I wake up. Whew! It was just a regular dream, not a dream come true. I get up and go back to work on my REST book.

Ruby is awesome and the Ruby Cookbook was a lot of fun to write, but it wasn't my idea. It's part of a high-profile O'Reilly series. There was destined to be a Ruby Cookbook, written by somebody, from the moment Rails strapped an E motor to Ruby and hit the igniter. This book was my idea, and Sam and I are driving it. In the coming months I'll be writing a lot more on this topic. There's a lot of work we need to do in the real world, in addition to writing stuff down in a book.

PS: I say this on the homepage for the book, but in case you haven't clicked through and you're interested in REST, please email me or Sam. We'd love to have you help us with the folklore and best practices, and we need lots of reviewers.

Daylight Come And It Won't Go Home: I probably shouldn't have announced my book project on a Friday afternoon. In my defense, yesterday I thought it was Wednesday. But the book gotten a huge reception to the point that I can only hope we can meet everyone's expectations. A huge number of smart people want to review the book so I feel pretty good about it.

Let me talk about light pollution. Recently I moved to a place where I have around 18 million neighbors. A lot of these people like to leave lights on at night. The effect is that every night the sky glows about as bright as the full moon (there's also a full moon tonight, which isn't helping). With curtains I can get a simalcrum of darkness, but I haven't seen (or, rather, been unable to see) real night darkness in months.

Now, I've seen the stars and they're not going anywhere, I don't need to look at the stars every night, but this lack of darkness is taking a toll on me. We're now at a point where there's about the same amount of ambient light from 5PM to 7AM, and the rest of the time there's normal daylight. I've never had any problems with SAD before I moved to New York, so I think it's not the darkness that's bothering me; it's the fact that it never gets really dark.

[Comments] (6) TMLMTBGB: Aaron Swamp Swartz is in town staying with us, and we just went to see the Brendan-endorsed play "Too Much Light Makes the Baby go Blind", which is now also Leonard-endorsed. They have an hour to do 30 pieces of sketch comedy and sketch tragedy, ordered according to audience demand. Highlights included "Legoland Theater Presents: The Medieval Epic" and "Bite this, Reality!". Lowlights included preachy political Colbert Report ripoff. There is audience participation (one of my bugbears, or even owlbears), but it's easy to avoid by not sitting at the edges. Dadaism lives! Kind of. The group is called the Neo-Futurists but there was actually no Futurist content unless you count the idea of man as a slave to machinery (in this case the clock).

Also, almost everyone in the cast looked like someone else I'd already heard of. So you could pretend that the skits were being performed by an ensemble of Owen Wilson, Simon Pegg, Pauline Yates, Sumana's friend Steve Schultz, Aladdin Ullah from Uncle Morty's Dub Shack, and Jacquelyn, who I couldn't think of anyone she looks like.

[Comments] (1) : I keep getting spam with subjects like "Po..s.sible meeting" and "Fri.en.dship", and thinking that they're advertising hot new Web 2.0 sites.

Taxonomy of the Programmable Web: As I've learned more about REST (including formulating the ROA) I need to go back and rewrite the first few chapters. This entry is part of my attempt to document what I've learned since then. As I write these entries keep in mind that I'm not any kind of expert, I'm just a guy who decided to figure out REST and write a book about it. So if you disagree or think the something is called the wrong thing, leave me a comment or email and we'll figure it out.

The first problem is to sort out the terminology. There are many ways of classifying services, and we're introducing two more in the book: "Resource-Oriented Architecture", which I've mentioned before, and "The programmable web", which is a way of saying "web services" without implying Big Web Services, or even saying the word "services". We got the latter term from the excellent programmableweb.com. (We also introduce "Big Web Services" itself, which is a way of saying "web services" and implying only the SOAP/WSDL/WS-* stack, but I think I'm going to use that term a lot more in these entries than in the book.)

The main work thing I did today was draw diagrams: a taxonomy and Venn diagram. Don't worry, they'll be redrawn by real graphic designers before they're printed in the book. One or both might make it in; the Venn diagram is simpler but the taxonomy has examples and chapter references.

Both diagrams show two decisions I've made for the book: first, we draw a distinction between Resource-Oriented and Service-Oriented architectures. Second, we define HTTP+POX as a hybrid of the two architectures. The former because it's not useful to pit a technology against an architecture (as in "SOAP vs. REST").

The latter because the web services described as HTTP+POX, the ones that are kind-of-but-not-really RESTful, tend to deviate from REST in the direction of RPC and the Service-Oriented Architecture (rather than having no architecture at all, which was what I expected). Examples include the Flickr API, which includes explicit method names ("flickr.photos.search"), and the del.icio.us API, which has special URIs that you GET to invoke particular methods ("/posts/delete").

Some interesting edge cases: almost all web applications can be considered HTTP+POX web services. They're usually not all that RESTful, but they take standard HTTP requests with non-fancy entity bodies, and serve a non-fancy XML dialect (HTML or XHTML). This is how libraries like WWW-Mechanize look at the web.

In fact, I suspect the combination of URI- and RPC-based architectures to form HTTP+POX comes from our experience writing apps for the human web. You can't do nontrivial REST in a web browser without Ajax. HTML forms only support GET and POST, they don't let you set request headers, and they have hard-coded destination URIs (this is why URI templates are going to be great).

I used to think that, while the lack of PUT and DELETE was lame, people who obsessed about those methods as a determiner of RESTfullness were just being pedantic. But the ROA/SOA classification shows why it's important: if you have to overload POST, you end up creating extra URIs which the client POSTs to in different circumstances. This puts you well down the road to the RPC model. Your URIs no longer point to resources; they point to procedures you can call by POSTing. It's natural to keep following that model when you go from writing a web app for browsers, to writing a web service for computer programs.

Another edge case is that a website full of static pages is technically a RESTful web service. It's composed of resources (files), each with one URI and one representation (the data in the file). Each URI correctly supports a subset (GET and HEAD) of the uniform interface. This is how libraries like Beautiful Soup look at the web.

If you look at the Venn diagram you see that the entire human-visible web (static websites and web apps) is part of the programmable web. This is quite intentional. People were programming to the web long before anyone started talking about "web services". It's dirty work because the human web wasn't designed with software clients in mind, but sometimes it's the only way to get the data.

There's one thing in the diagram I'm not clear on. It might be a minor point or it might be an important aspect of our definition of HTTP+POX. The question is whether there are web applications that are so RPC-oriented they cross the limits of HTTP+POX and move in on the architectural turf of SOAP/WSDL services. I drew the Venn diagram with web apps that were neither REST nor HTTP+POX, thinking of really monolothic web apps that only expose a single URI, and do everything by POSTing to that URI.

The "POX" in HTTP+POX basically means "no SOAP", but what specifically don't HTTP+POX people like about SOAP? Is it the complexity of the SOAP message itself? Plain old XML can get pretty complex too. Or is it the fact that the SOAP message contains information (like the method name) that they think should go in the URI?

There are also, as one emailer pointed out, problems with calling anything a "web service" if we're drawing distinctions between a "service-oriented architecture" and something else. I'm not sure what to do about that. I'm tossing around the idea of switching that label to "RPC-oriented architecture", but I don't want to introduce yet another term of art.

open-uri ought to be a REST client: I spent a lot of time and used a lot of pages in the Ruby Cookbook showing how to use Net:HTTP to build more and more capable HTTP clients that hid the hairiness of Net:HTTP. But in truth the open-uri library, which we only covered a little, supports almost every feature you could want from an HTTP client library: custom headers, proxies, transparent HTTPS with cert validation, even automatic handling of the redirects it's okay to handle automatically. And the interface couldn't be simpler: it overloads Kernel#open so that you can open an HTTP request like a file, and read the response like data from a filehandle.

I'd like to recommend open-uri for everything, including as a client for REST web services, but there are two big features it's missing. You can't use any HTTP method other than GET, and you can't send any body data (which makes sense if GET is the only supported method). Lately I've been building on my Cookbook work, coming closer and closer towards a general HTTP client library for Ruby, but really all I'm doing is reinventing open-uri with two extra features. It would be a lot better to just add those features to open-uri.

I submitted a patch for open-uri on this topic a while back but have yet to get any response, even from people saying it's stupid. I'm writing REST clients with open-uri under the assumption that that'll work by the time the book is published. For instance, here's some code from my Amazon S3 client:

  # Saves this bucket to S3.
  def save
    open(uri, :method => :put)
    return self

  # Deletes this bucket and all its contents.
  def delete
    open(uri, :method => :delete)

I guess you could argue that these features break the metaphor, that PUTting to a URI isn't really "opening" it, or that it's like opening a file for write access and you should have to write the body data inside a code block the way you do for a file.[0] But c'mon, let's have that argument. I don't want to have to keep telling everyone about fake reimplementations of open-uri just so they can write REST clients in Ruby. There's also precedent, like XMLHttpRequest.open in Javascript.

I'd also like to add caching support to open-uri, like the caching support in Joe Gregorio's httplib2 for Python. But I'll wait on that until the fate of this simpler patch is decided.

[0] I doubt this is really the intent of open-uri, since right now it doesn't support HEAD either. I think the intent of open-uri is to make it trivial to make an HTTP request from Ruby.

[Comments] (5) Amazing Science: Pulsating Gels Could Power Tiny Robots. Hey, what couldn't power tiny robots?

[Comments] (1) Argh: Have to go another round with the post office. So aggravating.

[Comments] (2) Nomenclature: Some good pushback on the Venn diagram and ROA/SOA dichotomy, primarily here at Labnotes. But also in some emails saying what amounts to: "Why are you putting 'services' in the name of your book if you then go and classify REST outside the Service-Oriented Architecture, today's hot buzzword that has 'service' in its very name? Why are you even saying 'web services' at all if you think REST is different from anything service-oriented?"

Good points, and highlighting an increasing source of uneasiness on my part. Which is good, despite the fact I generally don't like uneasiness, because it shows it's paying off to embarrass myself by formulating this book in public. People are interested enough in the topic to form uncoordinated revolts around ideas that are wrong or need work.

First a disclaimer about how much this matters: not a whole lot. This is a book about REST and the ROA. The name of the ROA might change yet for marketing reasons, but we've got its technical features pretty well defined. There is a chapter (#1) that covers the programmable web as a whole, a chapter (#3) whose first half covers services popularly considered RESTful that aren't really, and a chapter (#8) that compares REST/ROA to "the other guys".

I was calling "the other guys" "SOA" but that's starting to seem wrong. My current wild hare is to call them "Message-Oriented Architectures", though that has a bit of a collision with Message-Oriented Middleware. That way "Service-Oriented Architecture" is freed up to describe a higher-level architecture based on providing and consuming web services (ROA or MOA or both). Which seems closer to existing usage of "SOA", insofar as "SOA" means anything besides "your new issue of BusinessWeek is here."

Point is, our taxonomy could change completely and we'd only have to make real changes to those three chapters (and #8 isn't even started yet, partially because we're trying to sort this stuff out first). More important, much more detailed, and hopefully less contentious, will be our description of what goes on inside the "REST" part of the Venn diagram.

Anyway, our task here is the Confucian task of the rectification of names. We're trying to classify the set of techniques and technologies used on the programmable web. If it turns out to be best described with gradients instead of subsets, it might be a 2D or 3D map instead of a Venn diagram or taxonomy.

This doesn't have to be like the Linnean classification system where everyone signs onto it for all time, but it should be done with respect for the way "the other guys" see themselves. Sometimes in the text of the book we'll poke fun at what I call Big Web Services0. But we need to have a credible story about what Big Web Services really are, how they differ from RESTful web services, and what lives in between. Ideally someone who disagrees might say "Well, I wouldn't call it that, but I see how you draw the distinction."

So here are some unsolved mysteries of our taxonomy:

I don't think anyone will dispute that there's at least one rival web service architecture to REST/ROA: the RPC architecture that shows up in many web applications, in web services like Flickr's, and in XML-RPC. Can we consider this architecture as similar to the message processing architecture that rarely shows up in web applications, and that is commonly associated with SOAP? That is, granted there are differences, do they matter for a book about REST, or do they both differ from REST in a way we can capture in some snappy term like MOA?

Are all these architectures mutual opposites, or points on a gradient?

It it useful to distinguish between the typical robotic SOAP/WSDL interfaces autogenerated from Java or .NET code at the touch of a button, and the in potentia SOAP architecture that can be anything, even RESTful?

Consider the services popularly considered RESTful but seriously non-thesis-compliant. We currently term those things "HTTP+POX" in deference to common (kind of common) usage. Is that just another case of conflating architecture and technology? Is it worth coming up with another term? And given that there are multiple rival architectures for web services, do these not-quite-RESTful services consistently deviate from REST in the direction of some other architecture, or are they just freakish one-off mutants? Are they the missing links on a gradient between the rival architectures?

0 Said like in one of those political ads with lots of black-and-white closeups: "Senator Bedfellow doesn't want you to know about his millions in contributions from Big Web Services. When the FBI came knocking, he started shredding the XML documents. But he forgot to shred the envelopes. Senator Bedfellow: wrong on URIs. Wrong for the web."

: As is all the rage, I have started posting book-related links I want to find or track under the del.icio.us tag restbook. If you want me to see a link, you can post it there. If you're secretly writing a REST book of your own and my tag cramps your style, let me know and we'll settle the namespace collision on the field of honor. Or the field of me renaming my tag to "oreillyrestbook".

: Who would send me a Nethack T-shirt to congratulate me on my first ascension?

He's Seth David Schoen!

[Comments] (6) Taxonomy of the Programmable Web! Part Deux: I know you're all for some reason anxious for the next report on my book progress. Well, in public it's all high-level philosophy but really the bulk of my day was spent chasing down Javascript and HTTP proxy hacks so I can finish "Ajax Applications as REST Clients".

However Sam and I did have a long IM conversation today, and cleared up a lot of taxonomy issues, as well as some of my misunderstandings about SOAP. I feel confident enough now to take another stab at my taxonomy of the programmable web. I got about halfway through before Ben came over to watch Battlestar Galactica, and that half is what I present to you tonight.

Again the disclaimer: though people will argue about these topics until the end of time, for purposes of this book we just need to get a coherent story about what it is we're cutting away as we zoom in on the programmable web to focus on the parts called "REST" and "ROA".

There are two major architectures on the programmable web. One is oriented around the passing of messages from place to place, and one is oriented around the manipulation of server-side objects called resources. We're (still tenatively) calling these the Message-Oriented and Resource-Oriented Architectures. Both architectures have real web applications and real web services to their credit.

These architectures can show up elsewhere than on the web, but we're not concerned with that. On the programmable web a service under either architecture uses the same underlying technologies: HTTP; a data format like XML, JSON, or form-encoded key-value pairs; and at least one URI.

Because they're built on HTTP, both architectures have a request cycle where the client asks the server to do something, and the server does it and sends a response. But we've found two questions which the MOA and the ROA answer differently:

  1. How is the request scoped? How does the client tell the server what part of the application it wants to operate on? Let's say the purpose of the request is to fetch some data. Why should the server send back data X instead of data Y?
  2. How does the client convey to the server what it wants the server to do? Why should the server send the requested data instead of modifying it somehow?

First a brief digression. When you send an HTTP request, you have two main options as to what to send in the entity-body. You can just send your data, or, if your data is an XML document, you can stick it in a box first. The name of the box is SOAP.

Just to avoid confusion: "SOAP" here is referring to the SOAP standard, not to the things people do with SOAP in the real world (that comes next). Sam says: "There isn't much to SOAP. It is three elements and a fault descriptor. Oh, that, and a world view." I'm just talking about the three elements and the fault descriptor. The worldview is the MOA.

Why would you stick your XML document in a box? Well, there are a variety of stickers that can be slapped onto the box without disturbing the contents. These stickers are the WS-* stack. That's the five-cent definition.

With that in mind, let's consider how the Resource-Oriented Architecture answers the two questions. A client for an ROA service scopes its request to a resource, by sending its request to a URI that identifies that resource. In an idealized ROA application there's one resource for every part of the application you might want to manipulate. Every resource has at least one URI, and you've got to send your request to some URI, so you might as well designate your resource by its URI. The URI goes in a special place in the HTTP request and can't be confused with anything else.

When conveying what it wants an ROA service to do to a resource, the client is restricted to a small and standardized list of methods. These methods are the famous HTTP GET, PUT, etc. Again, the HTTP method goes in a special place in the HTTP request and can't be confused with anything else.

If the client wants to convey an action that's not on that list, the problem is almost always that they've chosen the wrong resource. The service ought to expose some other resource for which the client's desired action translates naturally into one of the standard methods. The service might not actually expose this resource, but that just means the service can't do what the client wants. It's no different from the aggravation of a C library that's missing the function you need.

(There are edge cases I don't really understand, about overloading POST for atomic operations that span resources. I'm still trying to figure this part out. I think I may end up modelling this as a tiny MOA architecture inside the ROA.)

Now, depending on the service, when you need to send a document with your request, you might just send it as is, or you might stick it in a SOAP box first. The second possiblity, is, AFAIK, only theoretical. I don't know of any services I would describe as ROA where the client sticks its entity-bodies in a SOAP box before sending them.

This is partly for historical reasons. It's partly because it's simpler for the server to accept the entity-body as a document, instead of parsing it into a SOAP box covered in stickers, plus the "real" document. But it's mainly because HTTP already has stickers (HTTP headers). An HTTP request or response is already a box that can contain data and have stickers slapped on it.

HTTP stickers are more restricted in form than SOAP stickers, but they're good enough for most purposes. To the extent that ROA service programmers covet the features of WS-* stickers, they tend to devise ways of representing the same information in HTTP headers. Example: WS-Security's WSSE "ported" to the ROA as the X-WSSE header.

OK, enough about the ROA for a while. What about the MOA? And where do popular acronyms already in common usage fit in? Tune in tomorrow for the action-packed conclusion.

: Beautiful Soup used to stream election results in Lawrence. As part of big ole chain of hacks. Lovely.

[Comments] (3) Book Name: "Leonard is may be overly-self-congratulatory (perhaps with deliberate irony), but it sounds like there is a lot of demand for such a thing."

Always with deliberate irony, but my infernokrusher prose on the REST book page has two other goals. First, to market the book, to make people excited about it so I can ask them for help. Second, to act as a guideline and a goal. As the book nears completion I will find myself wrestling with the question of whether the manuscript does or does not put the "web" back into "web services". If it doesn't then we should probably do some more work on it. Does it drive all opposition before it, or is it just okay? Etc.

I'm exhausted, so no continuation of the taxonomy series tonight. But I would like to give an update on the name of the book. I got about 20 emails about it, almost uniformly against "with Ruby" in the title. On a semirelated note I can report that "with Ruby" is almost certainly gone from the title. The title is not finalized; editor Michael thinks "REST Web Services" is ungrammatical. But I think we agree on what kind of name will capture the goal of the book: an introduction to REST that has contains real examples but also has some philosophical heft to it.

The best argument for "with Ruby", I think, apart from "cheap trick to sell more books", is the same argument for using Ruby as our implementation language. We're not using Ruby because its XML support or HTTP client library is the best (it's not), but because Ruby is where the open source REST work is happening. This gives us lots to talk about without having to be polyglot throughout the whole book. Right now you don't see things like ActiveResource happening in other languages. (Note: this statement is precisely calculated to bring people out of the woodwork saying "you've neglected my awesome non-Ruby server-side REST tool!" so that I can take a look at said tools.)

The counterargument is that most peoples' interest in REST doesn't start on the server side. It starts when they write clients for big-company services like Yahoo!'s and Amazon's and Google's. They hear the term "REST" used (possibly incorrectly), and want to know more about the underlying architecture. There will always be more clients than servers, and the client programmers are using all kinds of languages.

Those whose interest does come from the server side are either trying to decide what to use, or just curious about RESt. Inside the book it's fine to say "Like REST? Your best bet right now is Ruby." But the book will fly past a chunk of its audience if the title says: "Like REST and Ruby? You'll like this book."

[Comments] (1) : Continuing my habit of clicking on Kris's ads I found the comic strip Station V3, which combines a ShaBot-esque sense of gag-based humor with a pretty good psychological study of being posted to a space station where nothing ever happens and you're surrounded by other dysfunctional people. A dimension that could be exploited to great effect by any number of other big-name media brands (I'm looking at you, Beetle Bailey), but never seems to be.

Strip includes cute fishlike aliens, and outdoes Battlestar Galactica in the low-tech science fiction aesthetic sweepstakes by having not just big clunky phones but big clunky payphones. Also you probably know this, but if you like science fiction comics with big space opera arcs and good character development you should check out Schlock Mercenary.

[Comments] (7) Return of the Son of Taxonomy of the Programmable Web: Previously, on Taxonomy of the Programmable Web, I put out a description of the Resource-Oriented Architecture based on its answers to these two questions:

Now I'm going to put out a description on the same principles of the Message-Oriented Architecture. Then I think I can make a case for how to classify weird cases like HTTP+POX.

To state the obvious (though it stops being obvious if you or we call the MOA something else), the Message-Oriented Architecture is about passing messages back and forth. Client sends server a message, server takes some action and sends client a message in response. A SOAP box with stickers on it is an example of a message. An HTTP request with headers is also an example of a message.

In an ideal MOA there is no information outside of the message. So if the message is in a SOAP box being transmitted over HTTP, then all the features of HTTP are just distractions and should be used as little as possible. There should be no leakage from the message into the transport protocol.

In the ROA, the fundamental server-side object is the resource. An ROA service usually has an infinite number of resources. In the MOA, the fundamental server-side object is the message processor, sometimes called an endpoint. A MOA service exposes a small number of message processors: usually one. A message processor is the thing that has a URI (or, possibly, the thing that can be the target of the WS-Addressing SOAP sticker).

Side note: A resource is just a message processor with a very limited vocabulary. So there's a pretty easy conceptual translation between the ROA and the MOA. This makes sense because HTTP is itself a message-oriented protocol. Of course, almost all ROA services expose too many "endpoints" to list. You either generate their URIs according to a rule, or you follow links in a document the server sends you.

An MOA might have ten or 200 or a million endpoints, but it's not ROA unless it has an endpoint or "resource" for every object the client might manipulate. Any service that exposes an infinite number of endpoints has at least some of the ROA in it.

This ties back into the famous triangle of "nouns" (resources), "verbs" (HTTP methods), and content types. The ROA constrains the "verbs" and lets the "nouns" run free. The MOA constrains the "nouns" and lets the "verbs" run free.

Side side note: an ROA service can contain a finite number of endpoints, but only if there's a finite number of objects the client might manipulate. A static website (like your cat's homepage, or the site that serves Google Maps image tiles) is an ROA service with a finite number of endpoints. A web service version of Parmenides's model of the universe would only have one endpoint, because there is only one proper object of discussion.

Now let's consider how the MOA answers the two questions:

How is the request scoped? Why should the server do x to data D1 instead of data D2? Well, in the URI it's scoped to the message processor. If your MOA service is actually ROA then that's all you need, because the "message processor" is the "resource" is the part of the application you're operating on. Otherwise, you need some additional scoping, and this is done by putting information in the message itself. This might be in the box or it might be in one of the stickers; the details don't matter.

How does the client convey to the server what it wants the server to do? Why should the server do x to data D1 instead of doing y to data D1? This too is scoped by information within the message itself. Again, this might be in the box or in one of the stickers; it doesn't matter to the MOA. Unlike with the ROA, the vocabulary of this sort of information is not constrained at all. If you constrained it you'd need to create more endpoints to handle the same actions with the more limited vocabulary, and you'd move towards the ROA.

Since in the MOA both of these pieces of information go into the message, there's a tendency to conflate them, and indeed that's what I used to do.

To recap from last time: the ROA puts scoping information in the URI, and puts the action information in the HTTP method. The big exception seems to be overloaded POST, where the action information can go in the entity-body. I'm now fairly certain that overloaded POST in the ROA is best described in terms of the MOA; I'll try to cover that next time.

Now I'd like to talk about a common design style for MOA services: the RPC style. In an RPC service, the scoping information corresponds to the information that would identify an object if this were an object-oriented program. The action information corresponds to a method that should be called on that object. As is proper with the MOA, both of these go into the message.

The message also contains some additional information, which corresponds to arguments passed into the procedure. The scoping information can be found among these arguments: things like the bank account number or the user ID. This is because an RPC service isn't really object-oriented. If it was, you'd be able to work directly with the objects (as, say, resources) instead of going through message processors. But with a little work you can get the same kind of "fake" OO you see in the GNOME project's C code, where the first argument to every function is a pointer to the "object". I put "fake" in scare quotes, possibly sending the most mixed message ever, because I think you can do real OO design in a non-OO system. But it looks strange, and you have to do work to get it.

In an RPC-style service, the HTTP request-response cycle is used to simulate a method or function call in a programming language. The request is the method invocation, and the response contains the return value of the method, or the exception it throws.

We all know that method calls are not neccessarily simple stuff where I ask you for information and you return it in a data structure. This "method call" might do anything: fetch information, store information, put a job in a processing queue, set up callbacks for later, etc. The response message might contain useful information, it might describe an exceptional condition, or it might just be a formality. If you register a callback the real data might be coming in later through the callback. So saying "RPC style" is not a negative value judgement about the capabilities of the style.

Let's take an easy case: XML-RPC. It's obviously an MOA architecture, since the only URI in an XML-RPC service is the URI to the XML-RPC service. It also rejects HTTP headers, methods, and status codes almost entirely, preferring to convey all information information in its XML message document.

It's also obviously an RPC architecture, because 1) it says so right in the name, and 2) its messages are full of incriminating tag names like methodCall and params.

Now, what about SOAP? Is SOAP an RPC style? No, that's a category error. SOAP came from XML-RPC (more accurately: they have a common ancestor) but they aren't the same kind of thing. XML-RPC is a way of describing method calls; SOAP is a way of sticking a message in a box and putting stickers on the box. This makes it useful for any MOA application, but it doesn't make it RPC.

So, riddle me this, Batman: how come basically the entire installed base of services that use SOAP also use the RPC style? Why does the average programmer think SOAP and then think RPC style?

SOAP is the message format of choice for automated tools that take Java or C# code you've already written, and with one click turn it into a web service. These tools are to web services as FrontPage is to web pages. The resulting "web service" exposes only one URI and accepts methods only in a very specific form that a person can't comprehend without a detailed map (a WSDL file) and a software tool on the other side (a WSDL client) that can read the map so you don't have to. When the software tool is done reading the map it's reconstructed something like the method signatures of the original Java or C# code.

This is why REST people dislike these services so much, and why that dislike often spills over into SOAP. This is why people tend to think that anything that doesn't fit this model is "REST". This is why I say these services are not really on the web: they're looking out at the web through a little peephole. To get any information out of them, you have to construct a very specific document, and then you have to put in a box and put the right stickers on it.

These services have the same design as XML-RPC services. They use XML Schema instead of XML-RPC's idiosyncratic data serialization format, and they use WSDL instead of the listMethods extension to XML-RPC. All the work done to make SOAP nothing but a good way of putting an XML document in a box and slapping stickers on the box, has passed these services by.

I don't like this because it's ugly and it pollutes the web. SOAP fans don't like this because it conflates SOAP with RPC when what they use SOAP for isn't RPC at all. I'm not really clear on what MOA styles they are using if not RPC, but I don't think it's going to come up a lot in a book about REST and the ROA, so I can just leave them to it and have Sam act as my lookout in case anything relevant to the book happens.

Who's the culprit here? I think it's those tools. They make it easy to get a web service that has the same interface as your code (that'd be a Procedure-Call interface that works Remotely), disregarding the fact that the architecture of the web doesn't look like that. Combine this disconnect with the complexity of the interface and the idiosyncracies of the tools, and you've made it easy for someone else to work with your service if they've got the exact same setup, and very difficult otherwise. This is pretty disgraceful since the real-world power of the web comes from its ability to connect everyone together.

The secondary culprit is WSDL. WSDL doesn't enforce RPC but it makes life easy for tools that want to force SOAP into an RPC mold. Sam is ambivalent about WADL. I suspect he's afraid that WADL will make it easy to force HTTP into an RPC mold, that tools for doing this will proliferate, and that we'll never see resources again. Sure, WADL makes you specify your resources, but a smart tool could easily subvert that and create services with a single "resource" that handles a whole bunch of method calls.

I think the scenario I've ascribed to Sam is not inevitable. A lot of the mess we see today comes from historical contigencies like SOAP's heritage in XML-RPC. But to prevent a future without resources we need a basic book that's willing to go out and fight for them. It means we need to straighten out the terminology—even if only informally and we only use the terminology locally—so we can create a frame for our argument.

Next time: HTTP+POX.

: OK, here's the deal. On any given day I can do book writing or I can write one of those big ole weblog entries. Today was book writing day. I got the "Writing Clients" chapter more or less done, bringing us to our milestone of having drafts of half the chapters. This is one of those milestones where I get paid, so I'm happy.

The Ajax chapter is also done, and I'd like someone who knows more than I do (ie. something) about Ajax to look at it.

: Picked Sumana up at work and walked down to Chelsea for dinner. My first choice, "Elmo", had no vegetarian entrees, so we went to a nearby place called Food Bar (not Foo Bar) that was good. We then walked to the Strand, where giveaway copies of books go to die, and Sumana found some cheap books she wanted. A nice evening out and a relief from looking at a computer screen all day.

Picasso: Today hung out with Evan and his father, which was a lot of fun. We went to the Whitney (conveniently hidden in a totally random block of Manhattan) and saw the Picasso exhibit. The theme was to have a Picasso, and then a bunch of paintings by other artists (Lichtenstein, Pollock, Jasper Johns, etc.) who'd ripped off the Picasso. It was pretty neat, and there was an Edward Hopper exhibit as a bonus. That guy's sketches are amazing.

There were two Picasso paintings (the really famous ones) that the MOMA owns and wouldn't lend to the Whitney. So the exhibit just put up the ripoff paintings and had tiny passive-aggressive reproductions of the originals along with explanations along the lines of "Girl Before a Mirror, in the collection of the Museum of Modern Arts since 1944, the cheap bastards!..."

[Comments] (5) The Rite of First Sale: Earlier I declared, "I've never done so much work for a hundred dollars." Well, I'm moving up in the world, because now I've never done so much work for two hundred dollars. I got email today saying that Futurismic bought my story Mallory!

This is great news for me as it demonstrates that I can write fiction people will buy. Look for it sometime next year, probably a little before the REST book is published.

[Comments] (1) Abbot and Costello Meet the Taxonomy of the Programmable Web: So far I think I've made a coherent case for classifying RESTful and resource-oriented services on one side of the Venn diagram, and message-oriented services on the other. The RESTful and resource-oriented services keep the scoping information (why should the server send you some dataset instead of some other dataset?) in the URI, and action information (why should the server send you the dataset instead of modifying the dataset?) in the HTTP method.

The MOA field is dominated by RPC-style services, most of which use SOAP messages constrained by WSDL files. The client communicates its desire by sending a message (a box with stickers on it) to a message processor, which unpacks the box to find both the scoping information and the action information.

We've got two edge cases to explain: overloaded POST and so-called "HTTP+POX" services. It's been said (see link at end) that I shouldn't try to fit HTTP+POX services anywhere at all because they're just a mishmash, but I press on.

We've also got an unexplained coincidence. I've been describing SOAP as a way of putting a document in a box and slapping stickers on it. But you can look at HTTP the same way. The HTTP request (or response) is the box; the entity-body is the document; and the URI, headers, method name, and response code are all stickers.

HTTP+POX, as they say, is a mishmash, but I think I can identify the things it's a mishmash of. An HTTP+POX service is a message-oriented RPC-style service that uses HTTP as the box format, rather than using SOAP.

This is most obvious if you look at how you modify the dataset in HTTP+POX services (I'm using the del.icio.us API and Flickr's allegedly "REST" API as examples). You either send a GET or an overloaded POST to a URI that's not a resource: it's a description of the procedure you want to call. There's a message processor for every operation, rather than just one (as generally happens with SOAP+WSDL services), or one for every object on which you might want to operate (as with resource-oriented services). Examples: del.icio.us /v1/posts/add and /v1/posts/delete, Flickr's multitude of methodName arguments.

The confusing part is this: when the RPC method you're calling is "get some data", the HTTP method is usually GET, and the arguments to the RPC method usually go into the URI. This URI designates a resource, and you can GET a representation of that resource! This is why I thought that HTTP+POX services are hybrids of the resource-oriented and message-oriented architectures. In many cases, the message is one you'd send if you were using the uniform interface to get a representation of a resource. The service may not have been designed with resources in mind, but this part of it is functionally resource-oriented.

Examples. Consider an endpoint of the del.icio.us API: https://api.del.icio.us/v1/posts/get?tag=restbook That doesn't have the same ring as http://del.icio.us/leonardr/restbook, but it's the same kind of URI. Those are two URIs to two representations of the same resource: "my recent posts tagged with 'restbook'". There are infinitely many URIs of this form, each identifying a different resource.

Similarly for http://api.flickr.com/services/rest?method=flickr.photos.search&api_key=xxx&name=penguin. We're supposed to interpret that as a remote procedure call, but it's also the URI to a resource: "Pictures tagged 'penguin'". Another URI to a different representation of the same resource is http://flickr.com/photos/tags/penguin. Even a URI like /rest?method=flickr.people.findByEmail&find_email=leonardr@segfault.org is the URI to a resource, though a better URI for the same resource might be /people?email=leonardr@segfault.org.

We have our own recommendations about how to structure URIs in a resource-oriented service, but it's pretty small-minded to say that services aren't resource-oriented just because their URIs look funny and contain things that look like method names (like "get" and "method=flickr.photos.search"). From a functional standpoint, these services stop being resource-oriented when they stop using resources. And, in general, they stop using resources when it comes time to modify the data set.

The method names in those URIs are useless to the extent they agree with HTTP's uniform interface. The "get" and the "flickr.photos.search" basically mean HTTP GET, and the client's already using GET. When those strings become useful ("add" or "flickr.photos.comments.deleteComment") it's because the RPC interface supercedes the uniform interface. The URI can no longer be conceived as pointing to a resource.

/rest?method=flickr.photos.comments.deleteComment&comment_id=100 could be one of many URIs to the resource "comment #100". Maybe the "method" argument is just random junk. Maybe if you GET this URI you get the comment, and if you delete this URI you delete the comment. But of course if you GET this URI you delete the comment. This URI doesn't identify the comment: it identifies an operation on the comment. That's not a resource. It's just a procedure call.

You can see this by looking at web applications. A web application like a search engine is pretty resource-oriented. It exposes an infinite number of URIs that slice up the search engine data in various ways: by query, by page, by language searched. All of these URIs point to resources. You can't see any cracks between the message-oriented and resource-oriented models, because 1) the "messages" you're sending are standard HTTP requests, and 2) you can't modify the search engine data through the web interface, so you only use GET and you use it as intended.

Then again, consider NewsBruiser, the weblog program that publishes these words. I wrote NewsBruiser before the term "REST" was coined, but it's pretty typical of examples even today. I've got URIs like /nb.cgi/add, /nb.cgi/comment-add, /nb.cgi/configure, and so on. In general GETting one of these URIs gives you an HTML form, which you fill out and POST to the same URI to modify the data set.

Even putting aside the fact that you can't do PUT or DELETE with HTML forms, this is a very RPC-oriented application. It's got method names in the URIs. Yet when you're not changing the application you're using URIs like /nb.cgi/view/nycb/2006/11/03/1. That's got a method name ("view"), but it's redundant with the name of the HTTP method (GET), just like with the del.icio.us and Flickr examples. The rest of the URI describes a resource: the second News You Can Bruise entry of the third of November, 2006. Indeed, I've got a rewrite rule that cuts out all the redundant and default data so that you can use /2006/11/03/1 instead.

So that's HTTP+POX. It looks like there are two main paths to this architecture. You might come to it by designing web services on the exact same principles as web applications. This overlaps with the resource-oriented architecture when that architecture congrues with the capabilities of web browsers (GETting data from resources identified with URIs, sending data to hard-coded locations). It departs from the resource-oriented architecture when it comes to things you can't do with a web browser (using PUT and DELETE instead of overloading POST so much, sending data to URIs that the client generated dynamically).

Or you might come to it through an attempt to simplify the RPC style. You might be doing pushbutton SOAP+WSDL services and one day say "screw only having a single endpoint; I'm going to have an endpoint for every procedure and it's going to be identified in the URI and then I won't need WSDL". Or you might say "screw putting an XML document in an XML box; I'm already using HTTP, I'll just use it as my box and then I won't need SOAP".

Now a word about the name. I've decided "HTTP+POX" is inaccurate and I think I won't use it in the book except insofar as I need to translate real-world terms into my wondrous precise terminology. Here's the problem: like "AJAX" of old, "HTTP+POX" hard-codes a reference to XML where there might not be any XML.

To reiterate one of my earlier points in new language: what's "Plain Old" about Plain Old XML? What's "Plain Old" is that it's a document, not a box with a document inside it. You've already got a perfectly good box: the HTTP request. But that's a statement about the box. "POX" is a statement about the contents, and those don't have to be XML. An HTTP+POX web service might serve plain text, JSON, HTML microformats, or graphic files in an HTTP box. This holds even if you don't buy my argument that HTTP+POX is an RPC-style architecture.

I can think of two different names. One involves doing what they did to AJAX and lowercasing the "POX", making it a word instead of an acronym: HTTP+Pox (HTTP can stay an acronym because you are using HTTP and only HTTP). This has the advantage that it's an almost invisible change. But depending on how cocky I feel about my classification of these services as RPC services, I may try to push the term HTTP+RPC. Because "Pox" doesn't mean anything, and I don't like the trend towards stripping acronyms of their meaning when it becomes inconvenient (as also happened to SOAP).

The next installments will cover what to do with terms like "Service-Oriented Architecture" in the face of definitions that would a priori prevent REST from getting any of the pie, and also finally tackle the question of overloaded POST in resource-oriented architectures. I think it's going to be a while until the last one, at least, shows up. Before I try to figure out overloaded POST I want to incorporate into the book text my thinking in the series so far.

[Comments] (2) : This one's pretty short; I just want to respond to Pete's entry about the term "SOA". I have largely bought into Assaf's assertion that defining resource-oriented services out of the SOA cuts them away from a large source of largess and buzz for no real reason. I don't really care about "SOA", but I do care about people spending money in the right places, so I want to leave the rhetorical ground open for those who can make that happen.

Pete quotes Anne Thomas Manes as saying:

Service oriented architecture (SOA) is a software design discipline in which application and infrastructure functionality are implemented as shared, reusable services.

As Pete points out this definition has a dependency on the definition of "service". Pete's definition is "a network available collection of related operations".

Okay, I'll buy that, and I'll also buy a $0.50 contract on Pete's "a resource is not a service". I'd say a resource is a service, albeit a very limited one that can only operate on one piece of data. An RSS feed is a good example of a one-resource service. But a collection of resources is definitely a service. In fact, "service" is what we call a collection of related resources.

A single resource can't have arbitrary operations, but you can expose arbitrary operations by exposing combinations of resources. It's not the same design as an RPC service, but only intertia associates RPC with "service-oriented" in the first place, and a service-oriented system could easily consume a mix of resource-oriented and RPC-style services.

A Plan Comes Together: with ElementSoup

: Spent most of the day doing Ruby Cookbook errata (new printing going out next week), which was pretty humbling. Also converting the REST book to Docbook, which is AGGRAVATING. Not least because I need to rewrite the first part of the book anyway and I keep conflating the Docbook conversion with the rewrite.

PSEUDO-UPDATE: I finally finished the errata and decided to put up an update. Then I saw I had saved this entry as a draft and not published it. So this isn't a real update. Incidentally, the previous entry was one I wrote back in August and saved as draft instead of publsihing.

[Comments] (2) : Sorry for no NYCB; been converting the book to Docbook and tearing apart the first part so I can stick Taxonomy of the Programmable Web stuff into it.

: Susanna and John are here for Thanksgiving and sightseeing. Susanna has a baby Beet inside her, as promised. Today we go to the park and the Met.

[Comments] (4) Borges: A Life: Been reading this book (the Williamson one) in stolen moments because it needs to go back to Rachel after Thanksgiving. It starts out really slow and boring but about 2/5 of the way in starts to ramp up and gets very interesting. Unfortunately 2/5 of the way is 200 pages, and it turns out you need most of that stuff because it's describing what later turns out to be the neuroses Borges can't get rid of for the rest of his life.

: Tomorrow: Susanna and I are in charge of Thanksgiving. It's going to be great.

I've got much of the REST book converted to DocBook and am putting what I write online. Send me email if you want to do review.

: From email conversation with Danny:

> Join me or die! Can you do any less?
I can't think of any way I could do less in general, but I'm always on the lookout...

: There are some kids who come out and play in the concrete "backyard" of the apartment building across from ours. That "backyard" is also where people stick their trash, and recently the kids' play has incorporated the trash.

There are two different reactions to this: "We must stop them!" and/or "I remember doing that sort of thing." I am in the latter camp because the kids seem to know what they're doing; they play with the abandoned furniture instead of rooting around in the trash bags.

Sometimes it I think they know what they're doing a little too well. A while ago someone threw out an old wide-screen TV (a big box for a plasma-screen showed up around the same time). The other day some kids were sitting in front of the TV, coloring with markers and pretending to watch TV.

Post-Thanksgiving Breakfast: Bowl of stuffing with fried egg on top. Delicious.

[Comments] (2) Cloisters: Today Sumana and I went up to the tip of Manhattan and visited the mini-Met museum of medieval art at the Cloisters (actual monastery cloisters imported from Europe). It's in a really nice park (Fort Tryon) so we also had fun walking around the park, and had a pretty fancy brunch at the in-park restaurant, New Leaf. We watched the sun set over the George Washington bridge.

Some funny bits of conversation from our day:

"Wel-come to the social! Zune you'll be dead!" <-Cryptkeeper voice
"I don't know how all these little stores can survive."
"They survive because there are millions of people here, and they all demand breakfast sandwiches!"
"And punctuation errors."
"Yes. They 'demand' breakfast sandwich's."

I got a Met membership so that I can go whenever I want without having to pay the exorbitant "recommended donation", or having to deal with the passive-aggressive consequences of trying to get in for less. Last time I was at the big Met I found out that my favorite objects d'art in that museum, the ancient Chinese office supplies, are part of a temporary exhibit that goes away in January. Go see that exhibit! It's great! And it also has a bunch of cool Xu Bing art that I just discovered last time.

Quick Restaurant Review: Annie's on 3rd Avenue between 78th and 79th. A little bit expensive, but good food and lots of it. Fairly vegetarian-friendly. Good place to eat after seeing museums.

[Comments] (2) : Misc. tidbits from conversation last night:

[Comments] (3) Karaoke For Beginners:

[Comments] (1) Shake Shack: Today I went to the Shake Shack on my way to the farmer's market. I went because it's supposedly a New York tradition, and pretty soon it closes until spring. I had a hamburger and a "concrete", which is a sort of thick milkshake made from frozen custard and extra stuff.

I've been to a frozen custard place before: Carl's in Fredricksburg, Virginia. So I knew what to expect. And it was good, except here I ordered a concrete that included Valrhona chocolate disks or whatever they're called. I didn't really know what they are so I said "Disks? Sign me up!" Then I got the concrete and remembered what Valrhona chocolate disks are. Those guys are great... FOR BAKING. For putting in frozen drinks they're not so great. It's like putting chopped-up Snickers bars in a milkshake and then crunching on frozen Snickers bar all the time you're drinking it. When you get a concrete, stick to extra things that are soft.

Hamburger: eh. I probably shouldn't even have gotten this since Shake Shack had about 150 health code violations (not an exaggeration) last time it was inspected. It wasn't very good. Andy and I have been going out on excursions where we try out the city's hamburgers, and Shake Shack is pretty lousy. I'd rate it below Burger Joint (trashy take-out burger restaurant in fancy Parker Meridien hotel, primarily famous in class-obsessed New York due to its class-transvestitism; there are celebrity autographs on the wall inc. Stephen Colbert's), which doesn't even use real hamburger buns. In conclusion: Shake Shack is for frozen custard with soft things in it. That stuff is good and you're likely to run afoul of fewer health code violations.

If you're curious, best hamburger discovered so far: Zip Burger at 300 E 52nd. They have Belgian fries too, and non-perfunctory veggie options.

1995 Follies: Sumana did a presentation for her corporate finance class where she pretended she was a Morgan Stanley investment banker trying to get people to invest in Netscape pre-IPO. I suggested she start off by saying "I bring you tidings... FROM THE FUTURE!". She said "That's basically what she [the professor] explicitly said we couldn't do."

So instead she talked about Netscape's server business and the promise of the web and blah and blah. There were Powerpoint slides, which seems somewhat anachronistic for 1995.

Anyway, this morning we were doing a postmortem, and the conversation turned toward the mid-90s integration of the proprietary online networks (Compuserve, AOL, etc.) into the Internet. Specifically, the common shunning of AOL users. Any mention of shunning calls to Sumana's mind Gentlemen's Agreement, specifically the scene where Gregory Peck can't get a room at a New England inn.

"Yes, I'd like a room." <- Rugged Gregory Peck voice
"Certainly, sir, I think we can accommodate you. If you'll just put your email address down to get on our mailing list."
"Ah. Oh, I see, sir. I'll be quietly shunning you now, sir. It's a free service we provide... FOR THOSE WE DON'T GIVE ROOMS."

: Well, my performance in this year's Nethack tournament was pretty lousy, mainly because it wasn't until around Tuesday that I thought "Hm, what would be fun to do in spare moments right around now? Oh yeah, Nethack." I did have one good character but killed her off stupidly.

Almost all of REST Web Services so far is rewritten and in Docbook. I planned to get the whole thing done by the end of the month, but that's just another goal I didn't meet: still have half a chapter to redo. I'm very happy with the first 5 chapters so far, though. Total length in O'Reilly's stylesheet is 200 pages. Again, email me if you want to read the REST book as I write it.

<M <Y
Y> M>


Unless otherwise noted, all content licensed by Leonard Richardson
under a Creative Commons License.