-
December 30th, 2007

Human hex. Gary Bernhardt has an interesting idea for human-readable encryption keys. Entering hex keys like ‘61aa60e43a5e7fdb4b86a4897b52a0dc’ is an excercise in counting sky-scraper floors. Gary solves that by encoding them to read like ‘BUSY BARN RUB DOLE TAUT TOOK ALTO PRY KIT WALL MUG CURT’. Not short, but definitely something you can read & paste.
Thinking, then typing. Guilty as charged:
If you are spending more time writing code, than thinking about what code you should write - you are doing something wrong. Very wrong. Or it’s something trivial enough to not be of much importance. Or it’s Java.
Thinking in types. Worthy as its own post, Nostrademons’s overview of typing strategies:
So basically, there are 4 dimensions:
- Static (expressions have types) vs. dynamic (values have types)
- Strong (values cannot be coerced to other types without a cast) vs. weak (the runtime performs a variety of coercions for convenience)
- Latent (no type declarations) vs. manifest (type declarations)
- Nominal (subtyping relations are declared explicitly) vs. structural (subtyping relations are inferred from the operations available on types)
Not quite SOAP. A sign of things to come?
So does this mean an about face for WSO2? Of course there is the famous April 1st blog from Sanjiva, but you can’t take that seriously! I don’t think you will see WSO2 dropping SOAP anytime soon, but these releases certainly signal a broader approach to SOA than just WS-*.
Year in review. And to end the year, a little Google mishap:
Google Reader: What part of “shared” and “public” did you not understand?
Teh People: Raise a hand, all who did not read “Burning Chrome“!
Lots of good wit spent on this incident, but my favorite is Paul Kedrosky’s overview of Social-Networking Tea-Pot Controversies, 2007:
But it wasn’t secure, of course. It was just a dopey feature, poorly implemented, and badly documented. In other words, it was normal software. And when Google finally, you know, made the Sharing feature share things — it linked your sharing feed to your address book — people got all pissy because a feature created to drive blind sharing of content with relative strangers began making it easier to blindly share content with relative strangers.
Hell, to adapt a cliche, hath no fury like that of a software user whose software newly works the way the documentation says it will.
Above, even Savage Chicken fears change.
Posted by Assaf
Filed in general
-
December 29th, 2007

Addressable. Bob Aman’s better URI library for Ruby (via Sam Ruby)
Er.js. Erlang-style concurrency with JavaScript. (Mini-rant: I wish people would stop calling it Erlang-style, just give Erlang credit for popularizing and it’s rock-solid/super-fast implementation of message-passing processes) It does require new features from JavaScript 1.7, so only Firefox 2.0 for now.
Lock & load. Jonathan Snook’s file upload forms that don’t suck is a nifty JS library that adds a touch of user friendliness and slickness to your file upload forms.
Fundamental. With notable exceptions:
Trying stuff is cheaper than deciding whether to try it. (Compare the cost of paying and feeding someone to do a few weeks of [Perl or PHP] hacking to the full cost of the meetings that went into a big company decision.) Don’t overplan something. Just do it half-assed to start with, then throw more people at it to fix it if it works.
(Via Kottke)
Stick figures. In the beginning, there was the flowchart… is a funny rant about the obsessive need to obfuscate code by diagramming it. While stick figures were all the rage in prehistoric time, a surprising number of people insist on using them for software design. This rant is for them.
Not that all diagrams are bad, as illustrated by this flavor.
Posted by Assaf
Filed in general
-
December 19th, 2007

Possible. Nathan Hamblen (Coderspiel) proves that there is life outside the IDE, using TextMate, Buildr, Jetty and JavaRebel:
A decentralized environment supports any underlying technology that the operating system supports. While IDEs struggle to keep up with the one or two alternative JDK languages to which they’ve decided to allocate resources, text editors support them all by default. As it turns out, languages that are less hindered by standards bodies incorporate exciting new features faster than IDEs can wrap them up in GUI packaging.
Too many lines. Speaking of IDEs, Steve Yegge has a long rant against them, more specifically the forests of code that prey on and feed them. I find it amusing that Steve, who can’t edit himself, rants against too many lines of code. Fortunately, Reg rewrites the entire rant in Ruby, so you only need to read the key points, and also reminds us of the real issue:
Instead, consider the cultural forces at work. Cultural problems cannot be solved with technology. If you are an advocate for change, ask yourself what sort of cultural change is needed, not what sort of technical problems need to be solved.
Minor correction. Discipline and Punish responds with a well made point:
And that’s when the ultimate reality of experience produces an even more terrifying truth: the failure space is much, much larger than the solution space. For every right way there are a thousand wrong ways that lead to doom. Mathematically, it’s hopeless.
Unfortunately:
Craftsmen are supposed to be different. They’re supposed to respect their tools and appreciate the great dangers that lie therein. They are, one might begin to naively hope, potentially the heroes who can slay the dragon of ignorance and save the day.
Craftsmen (gender non-specific) are different, they are responsible for finding the best tools, creating them when necessary. It’s the lay person who attempts to slay dragons by fixing their plumbing with a swiss army knife.
False dichotomy. Jeff Atwood: “Users couldn’t care less whether the underlying code is pretty.” Jeff cites as proof that ugly-as-hell Bugzilla is still being used by Apache. Except that it’s deprecated in favor of JIRA, new projects are set up to use JIRA and old ones allowed to choose their migration path. I would not approve any project I work on to use Bugzilla.
User’s don’t directly care what the underlying code looks like, but they do care that it meets their expectations. And if the only way to meet their expectations is make the code pretty, and therefore easy to maintain, so be it. The risk of assuming the user doesn’t care what the code looks like, is creating software the user doesn’t care to use. At all.
Like talking to a radio. JJD:
You probably noticed that the REST community has stopped talking with me. … These were the only two people that had the courage to go to the end of the discussion even though they saw some limitations to the REST approach. Others, have stopped all communication as soon as they understood the problems with REST.
Since I was named somewhere in that post, I may be one of those REST communitists. So let’s be cleared on why there are no substantial responses coming from my end. Until we can agree the Sun rises every day, there’s no point in us debating the, and I’m not denying there are, merits and drawbacks of DST, or what would be the most appropriate dates.
Photo, by christynski.
Posted by Assaf
Filed in general
-
December 18th, 2007
Those pesky 7%. Download Squad:
According to the study, 94 percent of US computer users have never tried a web based productivity suite. More than 20 percent say they’ve at least heard of Google Docs or other suites, but have still never tried them. And only 0.5 percent of users say they’ve replaced Microsoft Office with an online office suite.
Now before you rush to conclusions, here’s a quote from Steve Case, 1995:
I don’t see any evidence to suggest that this is what the 93 percent wants … I think a subset of the 7 percent wants that. The people I talk to who don’t yet use online services don’t use them because they are still a little scared of them.
PXSL. Stands for Parsimonious XML Shorthand Language, which, if you only read the first few examples, looks like yet another bracket-less syntax for XML. It’s the shorthands that make all the difference, and you’ll find them in the advanced section:
template /
for-each /foo@href
value-of .
text <<,>>
BTW the / is XPath not a PXSL symbol, and this example requires that you have some XSLT comprehension skills.
A/B testing. Michael Kölling on what needs to be done to get closures in Java:
We should take a prototype and get real, average users to work with it for six months, and have a proper evaluation to see what happens. We can find out whether people can really master it. And whether they find it useful. Not the experts, average users.
Tim Bray:
But you know, I could be wrong. Maybe there’s a way to build closures into the Java language in a way that’ll add power smoothly with no real downside. If that’s true, we need to discover it and prove it, and the JCP isn’t about discovering things; it’s about the worst possible place to approach this problem. Now that Java is Open-Source, anyone can go cook up whatever loony closure facility they want, and if it’s good enough, people will start using it whether the binary build has “Java” stamped on the outside or not, and then start shouting that it should be in the standard distro, and only then should the JCP consider going near this tar-pit.
I’m also a JCC (Java Closures Contrarian), but I’ll flip-flop when I see developers jumping up and down with joy after getting to experience closures first hand. So how hard would it be to put a closure on this theoretical debate and just test it in practice?
Focus! Interesting point from Corticon’s David Straus:
Business rules, like tasks in processes and lines of code in functional programs come out of the discussion of decisions to be understood and eventually automated. So when I hear people ask about capabilities to manage a rule I ask myself, when was the last time I heard anyone talking about independently managing a line-of-code. The result of this history is that this thinking has added far too much complexity to the task we have given our business rules customers. Instead of thinking about discovering, modeling and automating the top 250 decisions within their organization, they worry about the 10,000 or more rules that exist to implement these decisions. That becomes a daunting task.
Trap door. Jakob Nielsen on the dangers of blindly copying the Web 2.0 meme du jour without paying attention to the context of your application:
The bottom line? While a modest 2.0 infusion can be beneficial, advanced features are rarely the most important contributor to good user experience or profitable websites. If you get caught up in the hype, you divert attention and resources from the simpler things that really matter. This opportunity cost is the real reason to take it easy on Web 2.0.
Posted by Assaf
Filed in general
-
December 17th, 2007

Consistency. I’m not a fan of consensus-driven specs, they sound great in principle but end up being worse than mediocre. Better yet to have point person responsible for the spec, and a few to choose from. James Bennett on why BDFL is the best strategy for evolving HTML:
And the same is true in many other successful open-source projects: Perl, Python and Ruby, for example, all have open development processes, but ultimately remain in the control of a single “BDFL” and/or a few “lieutenants”. And the success of these projects across a broad spectrum of their target markets shows that this process can work extremely well: a general patten of open input and discussion, with a few experienced and trustworthy folks who steer the process and have the power to make final decisions when things would otherwise get bogged down, manages to avoid the downsides of both of the extremes of the false dilemma outlined above.
Integrity. Adam Gomaa has a quick reminder that frameworks exist for conceptual integrity:
When there is no conceptual integrity, a product is unusable as the basis of further programming, and a product with no conceptual integrity is fundamentally incomparable to one that does.
Both links, via Simon Willison.
Isolation. Paul Fremantle of WSO2 is reclaiming the ESB:
Fundamentally, the difference is that the conversion from internal formats and models to the common uniform model happens in the center – in the “ESB” – and is not owned by the application owners. This is actually an Anti-SOA pattern. The single most important aspect of SOA is ownership. The point of a service provider – in real life as well as IT – is that they take full ownership of the problem domain.
Buzzword compliance mandates use of the CIO Approved(™) TLA, even though Paul’s ESB is more of the distributed network of services architecture, rather than the anti-pattern J2J integration stance taken by most other vendors. Quite unfortunate buyers can’t tell them apart.
Testing. RSpec 1.1 is out. Nested contexts and a better syntax for shared behaviors, which I’ve been hoping for since before 1.0. And a few minor bugs that annoyed the hell out of me are nicely fixed. Yay!
Very interesting, but I don’t agree with you. Chris Cameron, still on the case to find out the true identity of Idetrorce. Not need to panic (yet), but don’t say I didn’t warn you:
How safe are you from Idetrorce? Do you really want to know?
Above, anyone knows what this is? (via ffffound)
Posted by Assaf
Filed in general
-
December 17th, 2007
Michael Pittaro raises an interesting point:
We often operate on the assumption that API’s matter as much as functionality. Although it’s always a pleasure to use a well designed API, in any language or any style, I’ve seen as many bad API examples as good ones. And it seems that in many cases, the API is secondary to the functionality - if someone needs the functionality, they will get around API hurdles.
But is this really the case?
SOAP as a concept is appealing to a lot of people, I think for much the same reason EJB was (still is?) appealing: it looks more complicated, and therefore must somehow be better.
But SOAP as a concept is nothing more than XML/HTTP with an envelope thrown in for good measure, which means you can easily reduce from one to the other. The same service can do both, they just happen to be two flavors of the same API. And if you’re worried about tooling, don’t: WSDL 1.1 is equally uninspiring at either one.
So it really doesn’t matter which one you choose, the functionality is all the same.
But what if you build an API around the capabilities of REST? Say, for SimpleDB. What if queries returned links so you can traverse the graph? What if each resource had both XML and JSON representations? What if you could cache results and not bother processing items unless they changed? What if you could use ETag to update items, detecting and avoiding conflicts?
All those are interesting features, but if you take a RESTful service like this and reduce it to SOAP, you lose them all. You’re not just swapping one interchangeable format for another, but trading one set of features for less.
And the same thing is true if we design the whole thing around the WS-* stack. Not the conceptual SOAP, but the one mandated by the larger stack. We probably won’t use WS-Tx, but maybe asynchronous updating using WS-RM, or we could using WS-Eventing to listen to changes, or how about a standardized security framework?
Here too, taking a WS-* service and reducing it to REST means losing some powerful features. In fact, SimpleDB offers a nice example in the way it uses WS-Sec/X.509 for SOAP and some horrible hack for signing non-SOAP requests.
Basically, if you start with REST and WS-* as architectures to build your services around, they cease to be protocols you can abstract away. As architectures, each offers unique features you can take advantage of.
It’s only when you’re building services around the architecture of mediocrity, that they blend together as two indistinguishable protocols. And it seems like there’s an equal number of people that believe XML/HTTP fundamentally needs SOAP, or that think SOAP without the envelope is REST. But then again, they might all be the very same person.
Posted by Assaf
Filed in general
-
December 17th, 2007
1999 called, they want their CGI scripts back.
I think that pretty much sums up people’s response to the horror that is the SimpleDB API. By which, I mean the few of us who can tell what’s wrong with it. Which sadly is not that many people.
But offending it is, and much like MySpace, I can’t bring myself to use it. So I decided to do something about it. Subbu came up with an interesting proposal for a RESTful API for SimpleDB:
In this exercise, my starting point was Amazon’s definition of the REST API, which I refactored into a RESTful version without breaking the usage pattern. Several variations of this approach are possible, but the key point to make is that (a) it is important to identify what the resources are, and (b) then think of mapping various operations into known HTTP verbs for the API to be RESTful, without losing focus on the net benefits of building an API over HTTP. This is not hard.
Not hard at all, Subbu. I took that idea and ran with it, creating DeHorrible.
DeHorrible is a Rails proxy that RESTifies SimpleDB. Or if you insist, GETStifies your resources to use SimpleDB. Either way, it will keep your sensibilities intact. I ended up with a slightly different resource mapping:
- POST /domains, using either name query parameter or name in body, returning 201 with URL in Location.
- GET /domains, with optional limit and token query parameters, which brings you back a list of URLs, with which you can …
- DELETE /domains/[name].
- GET /domains/[name], which takes the optional query parameters query, limit and token, and brings you back a list of URLs, one for each found item.
- POST /domains/[name] to create a new item, returning 201 with the URL in Location. Requires item name and attributes, either URL-encoded, JSON hash, or XML document.
- GET /domains/[name]/items/[name] retrieves all attributes associated with that item.
- PUT /domains/[name]/items/[name] updates (replaces) attributes with new values.
- POST /domains/[name]/items/[name] adds new attribute values.
- DELETE /domains/[name]/items/[name] does what you think it will.
Once you get into attributes (attributes/[name]) you can do a few more funky things like retrieve, replace and append individual attribute values, and delete an attribute of all its value, or a given value (attributes/[name]/[value]).
It uses HTTP Basic authentication, so plug your AWS ID as login name, secret key as password, and rock:
curl http://your_id:key@localhost:3000/domains -X POST -d HelloDomain
curl http://your_id:key@localhost:3000/domains/HelloDomain
So there you go. SimpleDB de-horrified. Now we can all sleep better.
The code is available here.
Posted by Assaf
Filed in general, ruby
-
December 16th, 2007

Pop-quiz. Name the API:
“I know, let’s remove the SOAP envelope and call what remains ‘the REST’.”
Apropos, GETSful.
Evolutionary. Linus Torvalds:
And don’t EVER make the mistake that you can design something better than what you get from ruthless massively parallel trial-and-error with a feedback cycle. That’s giving your intelligence _much_ too much credit.
The printable Web. What can you do with HTML and CSS? Håkon Lie and Michael Day on high quality prints, from pamphlets to books. If you’re still unconvinced HTML is print quality, give it a try. It will surprise you.
Idetrorce-ed. Comment left of my blog:
“very interesting, but I don’t agree with you”
Idetrorce
This looked strangely like no other spam, curiosity won, and I decided to Google for it. Turns out, Idetrorce is a force of nature.
Wear it with pride. Shirts for Ruby nerds and Rails junkies. (Via Ruby Inside)
Posted by Assaf
Filed in general
-
December 14th, 2007
Not that the first version was all that bad, but the second version is much better. Filters make all the difference (also some bug fixes):
class ItemsController < ApplicationController
before_filter :item, :only=>[:show, :update]
if_modified :item, :only=>:show
if_unmodified :item, :only=>:update
def show
end
def update
item.update! params[:item]
render :action=>’show’
end
private
def item
@item ||= Item.find(params[:id])
end
end
if_modified
The if_modified filter calculates ETag and Last-Modified values from the instance variable, and compares those to the conditional GET If-Modified-Since/If-None-Match headers. If the data changed since the last request, it performs the action and sets new headers on the response. If the data didn’t change, it sends back 304 (Not Modified).
That means you only need some minimal information to figure out whether or not the action should run its course. For heavy stuff, this can save you from loading a lot of data and rendering the response. And of course you can do it entirely from Memcached and save a trip to the database.
if_unmodified
The if_unmodified filter calculates ETag and Last-Modified values from the instance variable, and compares those to the conditional PUT If-Unmodified-Since/If-Match headers. If the data didn’t change since the last request, it performs the action and sets new headers based on the new (post-update) values. If the data did change, we have a conflicting update, and it sends back 412 (Precondition Failed). That’s sign for the client to retrieve the resource again and attempt another update.
You can use this one to solve the lost update problem. If two clients are updating the same resource concurrently, one gets served with a Notice Of Conflict, so it can safely run the update again.
It can also be used to reliably create a resource, which I’ll cover in a future post.
Usage
The first argument to either filter can be a method name (:item) or an instance variable name (:@item), or you can use the :using option with method name, variable name or a block.
Last-Modified is calculated from the update_at value, most recent if the value is an array. ETag is calculated by calling the etag method, a combined hash in case of an array.
This also means adding an etag method to your ActiveRecord. One is provided by default and will calculate a unique tag from the object’s attributes, or when using optimistic locks, the record’s id and version column.
Content type is also included in the ETag hash, so two representations of the same resource will not conflict in the cache. But as a side note, if you are using the same action to serve a page and a partial (for XHR), you’ll get two ETags and neither copy will be cached, so try using the .js suffix for the XHR URL.
Code is over here, and to install:
./script/plugin install http://labnotes.org/svn/public/ruby/rails_plugins/if_modified
Posted by Assaf
Filed in ruby
-
December 14th, 2007
Related. RDBMS vendors are not having the best day today. SantaAmazon delivers SimpleDB. Scalable, reliable, pay by the use, Do Your Own Consistency. And that’s after open-source came in to undermine the pricing structure. Big news.
SOAP without the envelope. On a sour note, and I quote from the SimpleDB documentation:
Amazon SimpleDB REST calls are made using HTTP GET requests. The Action query parameter provides the method called and the URI specifies the target of the call. Additional call parameters are specified as HTTP query parameters. The response is an XML document that conforms to a schema.
It gets better:
The following shows a REST request that puts three attributes and values for an item named Item123 into the domain named MyDomain.
https://sdb.amazonaws.com/?Action=PutAttributes&DomainName=MyDomain
And the response?
<PutAttributesResponse xmlns="http://sdb.amazonaws.com/doc/2007-11-07">
<ResponseMetadata>
<StatusCode>Success</StatusCode>
<RequestId>f6820318-9658-4a9d-89f8-b067c90904fc</RequestId>
<BoxUsage>0.0000219907</BoxUsage>
</ResponseMetadata>
</PutAttributesResponse>
Where did the REST go?
Eventually misconstrued. A lot of people are tripping over this, here’s one example:
This “eventual consistency” greatly limits what SimpleDB can be used for. Don’t try to use it to store any sort of accounting information, for example: If you adjust an account balance twice in quick succession (with each transaction being performed as a read-modify-write sequence) there’s a good chance that you’ll lose the first transaction because it won’t have propagated by the time that you read data for the second transaction.
Actually, no. What’s going to happen in this scenario is that you’re going to end up reading both values. Unless you mark it for replacement, each write will add a value to the attribute and the following read will return both, which you can then reconcile. It’s just a matter of handling consistency at read time.
Caching, (de)mystified. There’s another post in the queue about caching (if_modified is making a comeback), but meanwhile, do have a read through Mark Nottingham’s excellent tutorial on caching, survey of XHR caching support in browsers (guess which ones are broken?), and overview of ETags.
And now, for your moment of Zen. Annotation-Oriented Programming:
@ImplementedBy(ServiceImpl.class)
public interface Service {
Posted by Assaf
Filed in general
« Older posts
|
|