Use-case Driven API Design (part 1)

Preface

Rarely does one get entertained by reading software manuals, though Knuth’s The TeXbook is one notable exception. Rarer still is getting pleasure from reading guidelines for writing software. Imagine my surprise when I found myself reading and actually liking Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries by Cwalina and Abrams. The book was seriously fun and educational at the same time. It was hard to put down. One of the general lessons drilled into me from that book was the need to paper test an API. The authors stressed the need for an API to be usable by design, not by accident. And design takes hard work.

This is my first post is about API design - a mysterious mixture of art and science - about which I am passionate. Inspired by such great authors, my goal for you, dear reader, is that you find this post fun and educational. If not, at least I can promise that the pain will be short-lived.

Why a published API needs design

Design thinking is the name given to the movement that is bringing usability and visual design into the earliest stages of a products life-cycle. It applies to electronics, web sites, software, and any product that requires human interaction. It’s methodology includes a deep understanding of the user, the problem being solved, and the solution space. It encourages ideation (making a lot of crazy ideas for solutions), mixing and matching ideas, and experimentation. It is a lot like brainstorming in that regard.

Well, an API is a product that requires human interaction as well. The ‘P’ in API stands for ‘programming’, and at least for the present most of the programmers I know are human. Some day if we eliminate programmers we can shorten API to AI.

Why should an API design require any less thought than a visual UI? The target audience (we programmers) can’t be assumed to have any more domain knowledge than the user of the UI, and in fact we likely have less. As a profession we fall back too easily on the assumption that programmers will know what to do. We also assume that if the programmers make a mistake then QA will find the bugs.

Another strong argument for careful design is that an API has a long life and if successful will be read many more times than it was written. You might have 100’s or 1000’s of programmers reading your API and trying to make sense out of it. They will all trip over the same usability issues and find the different workarounds. Time invested in making an API usable pays dividends over its lifetime and can contribute to its success.

This post specifically targets the design of the published APIs for business objects. This is a subset of the more general area of API design. A published API is intended to be consumed by 3rd parties (either within your enterprise or outside of it). Thus the design of the API is more critical since it is hard to change. It is also harder to explain. APIs for business objects tend to be limited. Business objects have very rigid rules for mutation because the business imposes many constraints and invariants on those objects. These two factors influence the design of the API as will be seen below.

So how do we go about making an API for a domain object as usable and intuitive as possible, and what does this even mean? Read on!

Considerations for a Good API Design

An API is a projection of a model. If you have a service that your customers want to use they likely have a model of that service in their minds: the type of data it provides, what they want to do with and to that data, and so on. If your service mimics a traditional process or service then your customers may already have a model based on that in their minds.

Example. Shutterfly produces and delivers printed photo albums from pictures you supply online. The model I have in my mind when I use Shutterfly is based on my past experience of putting pictures into an empty photo album I purchased in a department store. I want the same flexibility in choosing the style of album, its dimensions, the number of pages, laying out my pictures, adding captions, etc. Shutterfly builds on that model in their UI and then extends it beyond the original, e.g. zooming in on a picture or applying filters. I appreciate these improvements to the traditional process. But the reason I find their site easy to use is because they use a mental model I am already familiar with.

A business API typically models data, not physical objects like photo albums. But that does not mean we are off the hook when it comes to the model’s design. For example, in an on-line library portal a user must first apply for an account (aka library card). The process should be modeled on the paper forms that a librarian gave you when you applied for your first a library card in a local branch. (I hope you still have your library card.) Of course this form differs from the form you filled out to get a driver’s license. While these forms collect some of the same data they also collect data that is unique to each application. A library does not require proof of insurance to issue a card and the Department of Motor Vehicles does not care about your literary interests. The nomenclature differs as well. To the library you are the borrower whereas to the DMV you are the driver. One way of putting this is to say that data has a shape.

Choosing the right model does matter. It may make the difference between an intuitive API and one that is clunky. If the model is not simple and natural for the domain, it will be fighting for user mind-share with the true model.

Once the model is chosen, the API must be designed to expose commands and queries against that model. These will again depend on the domain, and they should be separate. While you may be able to change your address on-line with the library application, the DMV will require you to bring proof of your new address in person. At least here in Michigan they are not very trusting. This API then becomes the projection of the model. It is not the entire model, but it is the part that external developers are allowed to see.

I propose four considerations, my four ‘C’s for a good API design:

  • Complete
  • Compact
  • Consistent
  • Clear (intuitive)

In the second post of this series I will elaborate on each of these in turn.