What makes a good API?


Creating an internal API. But when you are exposing it as a cross cutting API across a large system - or, to make that challenge harder, making it public - we always want the following objectives of a good API to be met.

  1. The intent is easily communicated.
  2. The expected behavior is executed.
  3. It is flexible, or perhaps versionable.

There are times though that some people get carried away with the coolness factor of some API design flavor.

“Fluent” API

Since the introduction of extension methods in .NET, a lot of the libraries like to provide a cool fluent-like API. While some of them really help with the readability of the client code (such as convention-based behaviors), it can be taken to an extreme where individuals go out of their way to avoid the new keyword to initialize a new representational object.

Consider the following code.

var response = request
                .SetThis(xxx)
                .SetThat(yy)
                .TransformIntoRequestResponseCommand()
                .SetOnConditionParameter(blah => blah == true, pppp)
                .FetchResponse(theRequestData)
				.AndThen(response => jjj);

Now, with the help of Resharper, I dig into each step of the method to begin to understand how something gets from a request stage into a response from the remote API. Readability? Not really, if you have to keep it simple, stupid!

request.This = xxx;
request.That = yy;

if (someCondition == true)
    request.ConditionalParameter = withThisValue;

var response = request.Execute();

// process response "AndThen(response => jjj)" as part above.

More lines on the client code side? Yes. But less digging for gold for the maintence programmer… you should be writing code for them, because they may dig a shallow grave for you since they dug deep for the bug under that large bunch of gravel.

Imitation Dressage

Nothing grates me more than seeing class after class which just acts as a proxy, or very then facade, into the meaty code. And then it is dressed over and protected by policy; not code policy, nor compiler policy - no - but with a lovely paste of bureaucratic policy.

I am going to nitpick one particular API which will remain nameless. But imagine that you have:

  1. A set of extension methods for the HtmlHelper ASP.NET MVC, which
  2. It basically does a very poor job of wrapping the baked-in HtmlHelper extension methods.
  3. And that there is always some error in it, but it cannot be fixed because you will break other things.

The biggest problem with this is that the whole motivation of the wrapping HtmlHelper extension methods is “so that they are able to change the UI design on whim of a requirement.” The only problem with these particular HtmlHelper methods is that it expects things in a certain order, and already lost the ability to flexibly alter the UI via CSS.

At the end of the day, it solved a problem which should not have existed in the first place. What it has done is that you solved a problem with - what I liken it to - “troublesome regex”, and now you effectively have two problems.

Conclusion

Really, it does come to keeping to the basic: if the intent of the API is simple, and it adds no unneeded burden to the user of your API, then you have a pretty good and sweet API.

blog comments powered by Disqus