Writing a new library? Sketch it out first

So you’re embarking on writing a new library. You might dive right in to the code and work straight on solving the problem or you might take a more considered approach and start thinking about how to model the problem, what classes and methods you need to create, how they interact and so on. However, rather than doing that why not start with sketching out not how the library works but how you would like it to be used. I think you’ll see pretty positive results if you try it.

Usability isn’t just for designers. If you want your co-workers or other developers to use and be productive with this code your creating its got to be as simple and fun to use as your user interfaces. Your library’s API is a user interface. History has shown that libraries and open source projects that put their API design up front are far more successful than their competitors. Take jQuery for instance, you can bet that when John sat down to create jQuery he wasn’t thinking “How do I animate CSS style?” or “How do I create and event system?” his main concern was how he wanted jQuery to be used. At least initially, the internals of jQuery were a mish mash of various libraries that came before it. What actually powered the explose growth of jQuery was the revolutionary API concepts it introduced: Method chaining, Selector-focussed API, simple plug in interface and so on. Other success stories like Ruby on Rails shared a similar focus on API design.

So, how do you write your code in such a way that it will make programmers happy and propell you into internet stardom? When you start out writing a new library or feature, start with a sketch. Cast aside any ideas that you might have already have about the implementation details and try to also cast aside any technical constraints and just start writing how you’d like your code to be used. Let’s take a DOM builder, for example. Mashing strings (or indeed using the terribly designed W3C DOM API) is no fun in JavaScript. If you were taking an implementation first approach you might start with an JSON-style data structure describing your DOM fragment or maybe even consider a set of objects that map to the various types of elements and this may well be how you implement it under the hood but put that aside for now. How would your code look when using the library? Here’s my first pass:

var fragment = build(
  div({ id: 'contact' },
    ul(
      li('Email: whatever@thing.com'),
      li('Twitter: ', a({ href: 'http://twitter.com/danwrong' }, '@danwrong')) 
    ) 
  )
);

Come up with the simplest, most aesthetically pleasing API you can and keep itterating on it until you’ve weeded out all the complexity you can. If certain arguments are optional or have a sensible defaults then make sure that the developer doesn’t have to worry about them unless they need to, is your library similar to any other library? If it is maybe its worth adopting the conventions of that library so it acts in a way that other developers expect it to. Developers dislike like reading documentation as much as your site’s users dislike read help pages. Strive for an API so simple that you can describe it in a few sentences.

Once you are happy with your sketch start building it out. You might need a little meta programming magic to realise the UI you are going for and that’s fine but use with caution. You need to weigh up whether the magic you are adding is going to make your code act in a way that is unpredictable to developers used to working with the language in question or if it will prevent developers from using their existing knowledge of the language to solve problems with your code. If you smell badness then leave the magic behind. In our example above we need to do quite a bit of work with the function arguments in order to support variable amounts of child nodes and to allow optional attribute hashes. In this case I’d make the call that this doesn’t add any extra confusion to the code so I’m happy to go with that.

Also, at this point consider how the API you are trying to design will impact real world pratical issues. For instance, in the example above it I would need to create functions for all HTML tags on the global namespace. Am I happy with my library a defining a global function called a()? No. Time to scale back on that idea a little.

Finally, when it comes to the implementation ensure that the architecture is sound and don’t try to couple the under the hood implementation with the API design to a degree that it’ll make the quality of the library suffer. I often view the API as a simple, pretty veneer over the top of a well crafted solution. Don’t hide the raw internals, make them accessable alongside the simple API. That way if the developer is on the beaten track they get a simple API but if they have specific needs they can delve right in and get stuff done.

So yeah, next time you write some code. Think about sketching out the API first rather than leaving it as an after thought. Your colleagues will thank you.

I’d love to speak more about this at JSConf. The competition is very hot but here’s my proposal if your interested. If it’s picked I’ll go in to detail on some great and poor examples of API design and also show off some nice techniques for bringing your API sketches to life.

Added OEmbed and Embeddable Player to twaud.io

I’ve just added OEmbed to twaud.io for fun and profit. I’d not really looked into it until Dustin and Russ pointed out and I really like the idea although it seems a bit under done at the moment (You can only have ‘image’, ‘video’ or ‘rich’ as media types. What about audio?). I’ve been meaning to implement an embeddable player for twaud.io for a long time so I decided to add them in.

The OEmbed endpoint is:

http://twaud.io/oembed.{format}

It supports JSON, XML and JSON-P (if you provide a callback parameter to a json request). For example:

http://twaud.io/oembed.json?url=http%3A%2F%2Ftwaud.io%2FYf&callback=myCallback

Returns this:

myCallback({
  "height":"65",
  "provider_url":"http://twaud.io",
  "title":"Little mix of all the dubstep tunes I've been listening to lately: WRONG BEAT",
  "type":"rich",
  "html":"<iframe allowtransparency='true' frameborder='0' scrolling='no' src='http://twaud.io/embed/Yf' style='width: 395px;  height: 65px; border: none;'></iframe>\n",
  "audio_type":"audio/mpeg",
  "audio_url":"http://twaud.io/audio/Yf",
  "width":"395",
  "author_name":"danwrong",
  "version":"1.0",
  "author_url":"http://twitter.com/danwrong",
  "provider_name":"twaud.io" 
});

The HTML property contains a snippet of HTML that renders the player:

All very beta at the moment but give it a try. Also, check the short dubstep mix I did a while back. Will post a longer one soon.

Massive Robot launches twaud.io

Well, it’s been a bloody long while again since I’ve posted here and I suppose you’ve all unsubscribed me now. To be honest, I wouldn’t blame you.

However, silence here does not mean that I’ve been sitting on my arse doing nothing. In fact, the reality is very much to the contrary. Loads of stuff has been going on but there are two new pieces of news. Firstly, I’ve renamed and rebranded my company. We are now Massive Robot and we are available for consultancy and development work so if you have anything in mind then please contact us. Joe has done the branding and it’s something I’m really pleased with.

Check the business cards…

Massive Robot Business Cards

Along with those is a new site and a T-shirt. The final and most important Massive Robot branding will be the kicks. I’m working on those at the moment.

twaud.io

This week launched twaud.io, Massive Robot’s new service. The idea is simple – it’s like twitpic but for audio. Go to the site or use the API to upload your audio and you get a page with a short URL and a player for your followers to listen to it. This is just the start and we are working on a whole load of new features for it so follow @twaudio to keep up to date.

The build of twaud.io has been an interesting and fun experience. I was able to use Twitter’s new OAuth based login process via twitter_auth which I’d recommend wholeheartedly for as a foundation for Twitter applications, although I have hacked to allow for both OAuth (for the site) and username/password based (for the API) authentication where normally you must choose one or the other. It also uses S3’s direct uploading facility via SWFUpload which was not easy to get going but has provided a really scalable system as the application stays completely out of the loop of the bulky upload process. I love the direction web development is moving in at the moment.

It's Been A Long Time...

But I’ve not just been sitting on my arse playing GTA IV, oh no. Well, not all the time anyway. The reason I’ve not posted anything (or been particularly active on the web in general) is that I’ve been damn busy. Most importantly, Catherine kindly gave birth to our first son, Max, back in March which has been quite a change and sapped a lot of my hacking time. I have to say though, despite the horror stories that many veteran parents like to feed you, our experience has only been good. In fact, not good, great. I recommend this reproducing lark.

Secondly, I’ve been hacking away nearly full time on one of my favourite projects to date, Peoples Music Store with LRUG stalwart and renowned anarchist, James ‘Bringing London To Its Very Knees’ Darling which is maturing nicely under private beta as we speak. Peoples Music Store is a great idea from some of the guys behind bleep.com whereby users can construct and customise their very own download store from the music they love then get free music themselves if people buy from their store. It’s a great way to both promote and show off you’re own music taste or in depth genre knowledge and find new music from stores you trust while getting some free digital swag along the way. I’m probably not explaining it well so just drop me a line if you want and invite and the site will explain itself. Public launch is coming in a month or so.

Building Peoples Music Store has been a great learning experience. We run the site on a cloud computing platform and from content ingestion to audio preview delivery to application servers to download packaging and delivery everything has been designed to scale horizontally – and I’m pretty proud of it. Thin, Rack, Sphinx, God, Starling and a whole load more cool open source gear is all running in there. I really need to get to blogging some of what I’ve discovered about working with Rack. It simply is the dog’s bollocks.

So, enough of the excuses. What’s on the horizon?

Speaking and Conferences

I’ve taken some time of speaking and conferencing in general so as to spend lots of time with Catherine and Max but come September I’m restarting the conference trail. Firstly, I’m doing a presentation and a tutorial (with Jarkko Laine) at RailsConf Europe all about JavaScript related Rails stuff and I’m likely to have a slot at @media Ajax as well. Also, I’ll be heading to dConstruct as is the tradition.

Hacking and Open Source Business

Although I’ve not commited to Low Pro or Low Pro JQ for a good while now they are both very much alive. I’ve simply not come across anything that I’ve felt the need to add for a while. If you have any suggestions or patches do let me know. I’ve actually got time to commit them at the moment. Another little project that I’m hoping to get off the ground is called Evil which is going to contain lots of Merb/Rack goodness. The first by-product of which is the merb_openid gem for consuming OpenID in Merb apps (it’s still not quite production ready though so don’t go using it just yet). I’ll let you know what Evil actually does when (or if) I actually get something working.

So, that’s all for now. Just a bit of a status report. I promise I’ll get some useful content written that you actually care about very soon.

Rails Archive RSS Feed

Rails Linkage