tags:

views:

208

answers:

6

Obviously, APIs have exploded over the past few years, but many of them seem poorly designed when it comes to utilizing them... I have an opportunity to design an API however I see fit, but I would like it to be easy to use for those accessing it. Of course, keeping it as simple as possible is a big help, but what are the gotchas that people have run into out there? Anything that should be avoided at all costs or implemented at all costs?

+2  A: 

I recommend you refer to Framework Design Guidelines.

alt text

this. __curious_geek
That is, if he is using .Net I'm sure if you are designing a Javascript API the conventions and such are way different(and I've had to suffer through quite a few javascript APIs that followed .Net conventions)
Earlz
@Earlz: I thought I was the only one who hated javascript code that read like c#; can anyone say AJAX extensions for asp.net?
Pierreten
@Pier nah AJAX has just a smell. To really appreciate .Net-icized javascript you must see DevExpress http://demos.devexpress.com/aspxperiencedemos/NavBar/ClientSideAPI.aspx `NavBar.SetSelectedItem(chbItemSelected.GetChecked() ? GetNavBarItem() : null);`
Earlz
Love this book.
SoMoS
A: 

Maybe you can begin by listing reasons for why you say "but many of them seem poorly designed when it comes to utilizing them".

Shantanu Mishra
+2  A: 

Despite this question is very subjective, the main thing to keep in mind is to keep what your API is designed to do easier to accomplish (write small ammount of code in a straightforward way) and make hard to do the things it was not originally designed to do.

To give you a very simplist example, let's suppose you are writting an API in C# and you have a method that returns a collection of items. Which type should you return? In this case you could ask the following question to help you to decide: I'd like the consumer of my API to change the collection (add or removing items)? If your answer is not, you should return a ReadOnlyCollection of items, otherwise you should return an List of items.

Continue asking these kind of questions to help you to better design your API. And always keep in mind the goals you had initially set for your API. Trying to be to broad is a very common reason behind many APIs become a Frankstein.

As another user said in his answer to develop an API along with a real system is always the best approach.

Carlos Loth
funny. I just read this article by Eric lippert, basically saying you should almost never want to return an array in C#. I'll let him word it better as I ever could: http://blogs.msdn.com/ericlippert/archive/2008/09/22/arrays-considered-somewhat-harmful.aspx
Toad
My intent was not saying that returning an array was a good practice, but to provide a relly simple example of trying to think about how the code would be use. I got your point, and I'll update the answer to use a ReadOnlyCollection.
Carlos Loth
Actually, I wouldn't return a ReadOnlyCollection either; returning an IEnumerable<> is more of a standard practice, and gives a pretty clear indication to a consumer of what they are supposed to do with the return value.
Pierreten
@pieretten: indication is not enough. If they can still change your values, when this is not intended, you still have to make copies of them before you return them.
Toad
@reinier: I think you are losing the focus on what I said. I said "a good API makes it easier to do what it was designed to do and it makes it harder to do what it was not designed to do". So, if you have a method that returns a collection that should not be modified by your consumers, return a readonly collection or an array. If would like to change the collection, of course you can, however you will need to write an ugly code to accomplish that. Thus, if you find yourself doing something ugly you can be sure that you are doing something that was not designed to be done.
Carlos Loth
@carlos loth: I hear your point. But too stress mine as well: changing an objects value which happens to be stored in an array is hardly considered ugly code. I would even say that I would expect these values/objects to be allowed to be changed. So by returning an array you MUST make copies of the objects stored in the array. And this could make quite a performance hit for large arrays.
Toad
+6  A: 

To create a great API, I believe it is vital to develop it alongside one or more real-world applications. Doing so lets you test how fully and elegantly your API addresses common issues.

Joey Adams
HUGE plus one. The only API's I use that were designed by me were factored out of actual applications.
Pierreten
Better "more" than "one", ideally developed by different developers than the API designer.
DR
+3  A: 

Checkout this tech talk "How to Design a Good API and Why it Matters". Covers some important points, and it's language-agnostic.

The slides for the above presentation are available here.

Some points that really resonated with me:

  • If you program, you are an API designer
    • Good code is modular–each module has an API
  • Hard to misuse
  • Write multiple plug-ins before release
  • Easy to read
  • Code should read like prose

For excellent examples of great APIs, I would suggest you take a look at these APIs (it's a community wiki so please feel free to add):

To contrast crAPIs from good APIs, see this common example of reading all lines from a file and printing them out. (Java):

BufferedReader reader = new BufferedReader(new FileReader("filePath"));
String line = null;
while ((line = reader.readLine()) != null) {
    System.out.println(line);
}

I have done file IO with Java on so many occasions and I still have to lookup how to do File IO every single time, and this is a terse way of doing things, for real.

vs (Ruby)

file = File.open("filePath", "r");
puts file.readlines

Another example from Javascript. Inserting and removing elements from a specific position in an Array is something you would suppose is a common task.

Here's how you can do it:

// insert element at index
someArray.splice(index, 0, element);
// remove element at index
someArray.splice(index, 1);

Now it's awesome that the designers have done an awesome job at code reusability, but I can't bother opening up w3schools.com each time I need to do this. So these simple wrappers get included as core extensions to Array in all of my projects:

Array.prototype.insertAt = function(element, index) {
    this.splice(index, 0, element);
}

Array.prototype.removeAt = function(index) {
    this.splice(index, 1);
}

Note: It's not about shorter code, but code that is simpler, easier to remember, readable, and consistent, among other things.

Also see this related question - http://stackoverflow.com/questions/469161/how-do-you-define-a-good-or-bad-api

Anurag
+1 for "crAPIs"
Gabe
What is a "crAPI"?
Carlos Loth
read it out as a single word.
Anurag
"crAPIs" parses as "crappy APIs", meaning APIs that are like excrement.
Gabe
+2  A: 

Write the client-code first. Ask your peers to write the client-code that shall use your API and evolve your design from client code.

If you are writing a Math api then ask your peers to write client-code as if they are using it. This will give you some good ideas to start with.

this. __curious_geek