Thursday, August 9, 2012

API design in Javascript


Three months ago I released an open source js library: occamsrazor.js
I firmly believe that it is very useful. Sadly I haven't had any real feedback (excepts Simone Orsi who stated "Cool experiment!" ... Thank you ).
I think It's important to listen to the feedback, even when there is not. Often people are too kind to give a sincere feedback when your work sucks. And if they don't understand what a library is for. They simply don't use it.

I slowly understood that a real example is very important to understand how a library can be useful.
So I started to work on a little demo (I'll release it as soon as possible).

Using my own library I started to think: "wow the library is useful but the API sucks !!!"

So I rewrote the API.

These are the lessons I learned:

Remove all the feature except the fundamentals

I usually follow this design principle:
"It seems that perfection is attained not when there is nothing more to add, but when there is nothing more to remove." [Antoine de Saint Exupéry]


So I decided to cut some features and voilà ! Everything starts to make sense.

Keep it simple

A good API must be easy to understand and remember: this can be obtained using short but descriptive names.
It is also important not to use an unusual calling scheme:

var x = Lib.executeFunc('foo', bar);

better:

var x = Lib.foo(bar);

Add syntactic sugar

A good API must be elegant. For this reason I borrow some nice Javascript tricks from jQuery:

  • chaining
If a method doesn't need to return a value is very useful if it returns the object itself. This pattern is called chaining. An example from jQuery:

$('p').addClass('foo').fadeOut();
  • object as function
A function in Javascript is an object. Like other objects we can freely add properties: to make an example jQuery has many methods (ajax, each, map, grep) but, at the same time, is a function returning a jQuery object.


  • signature polymorphism
Sometimes can be useful if a function acts differently when the parameters are different. If we don't pass an argument to a function that argument will be undefined. Furthermore every function has a local variable called "arguments" (an array like structure) that contains all the arguments passed to the function.

I hope this article will be useful.

The new version of occamsrazor.js is on github