Writing a new library? Sketch it out first
10 FEB
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
26 MAY
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
20 MAY
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…
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.
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...
23 JUN
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
- Writing a new library? Sketch it out first 10 FEB
- Added OEmbed and Embeddable Player to twaud.io 26 MAY
- Massive Robot launches twaud.io 20 MAY
- It's Been A Long Time... 23 JUN
- How Good Is This? 02 JAN
- The State (And Future) Of The UJS Plugin 16 JUN
- RailsConf Is Over: One Down, One To Go 21 MAY
- Off To RailsConf and @media America 15 MAY
- Low Pro 0.4 Released 16 APR
- The No Shit Guide To Supporting OpenID In Your Applications 27 FEB
- Coding Like A Bitch: Mephisto Plugins Upgraded and Fridaycities/EventWax Beta Biznizz 31 JAN
- MinusMOR Released! 24 NOV
- RJS Minus R 17 NOV
- Event Wax Is The First Production UJS Application 09 NOV
- RailsConf Presentation Slides and Example Code 18 SEP
Rails Linkage
- 3D Secure in Rails with Active Merchant and Sage Pay (formally ProTX) | Tekin Suleyman - Ruby on Rails Developer, Manchester UK forked version of AM with support for protx/3dsecure
- Protx Gateway is broken for use with 3D secure - Active Merchant | Google Groups Discussion of adding 3DSecure support to AM Protx
- josevalim's inherited_resources Nice version of the restful resource abstraction that has been attempted many times. It's a lot like mine but has some nice stuff based on Rails 2.3.x stuff.
- 8 Minutes On Rack Slides from my talk on Rack at Ruby Manor. I thought I could do Rack justice in 8 minutes...turns out I couldn't cover all the good bits.
- For attaching files, use Paperclip Really liking the look of this plugin for attachments. It looks a little like some of my own attachment code but I love the way they are using ImagickMagick directly...much much better.
- AP4R Wiki: HomePage
- Is your Rails app XSS safe? Documenting the pain of getting the Safe ERB plugin to work in Rails. Love the idea - just needs a little more work to act sensibly. I _might_ give it a bash on my latest project.
- No True "mod_ruby" Is Damaging Ruby's Viability On The Web I'm going to keep an eye on this. Hopefully it'll turn into an interesting discussion. Things like this make me want to get back into C.
- Beanstalk Messaging Queue Geoff's putting out some really good posts at the moment. This is a great overview of the messaging queues on offer for Ruby and Rails projects.
- Dive into Erlang