Making APIs usable

All APIs have end-users. How and whether these users use a certain API depends on how useful the API is to them. This in turn is determined by what problem the API solves, how easy it is to learn and understand, and how easy it is to use. This article will give some (perhaps obvious) pointers on how to improve ease-of-learning and ease-of-use of your API.

Usability is the science of usage which means that usability rules and laws apply to rich clients, web applications, paper forms, furniture, milk cartons, tools etc. It needs to be taken into consideration whenever there is a human end-user. If not, the product will be designed to be specifically useful to the designer.

Know your user

The first question to ask yourself is: Who is going to use your API? If you know that
then you are half way to the bank. Why? Simply because you know what your users
know and want, and thus you can give them what they need.
If the user has a list of objects and wants to remove objects which already exists in
another list, your API could look something like this:

CustomList myList = getMyList();
CustomList yourList = getYourList();

“myList.removedSharedItems(yourList);” describes what the function does to your
list, and is suited for most any programmer. If, on the other hand, you know that
your users are working with set theory, you would probably want to do something
like this:

CustomList myList = getMyList();
CustomList yourList = getYourList();

Let the API be self-documenting

Remember that when it comes to learning or getting started with an API, many pro-
grammers simply rely on the AutoCompletion-function in their IDE. If they don’t
get it from looking at that, they might turn to the documentation, or simply turn to
another competing API. So don’t take naming your classes and methods lightly.
In the previous example both




..mutate myList. This is visualised by using “remove” and “to” which both refer
to the myList-object. If for example “myList.toRelativeComplement (yourList);”
didn’t have the word “to”, the user wouldn’t know if it returns the relative comple-
ment or if it mutates myList to it.
In SpringFramework, self-explanatory class names such as “BatchPreparedState-
mentSetter” (an interface for a prepared statement setters used during batch up-
dates) are widely used. The only risk with this is that class-, interface- and method
names can get rather long, resulting in poorer readability. Explain what it does but
be as precise as possible and don’t take it to the extreme.

Don’t present the underlying implementation

The API should limit itself to what the user needs to know; no more, no less. The
names of classes, interfaces and methods should describe what they do and what
they are used for; not how they do it. Why force the user to know what the underly-
ing implementation does if they don’t need to know? Open-source your code and
give the user the choice to see how it is done instead of forcing it on them. takes an InputStream. This means that to load
properties from XML the following needs to be done.

File myProps = new File(“.MyProps.xml”);
FileInputStream is = new FileInputStream(myProps);
Properties p = new Properties();
//void loadFromXML(InputStream in)

The fact that loadFromXML takes an InputStream describes what the method does.
A better solution would be to look at SpringFramework’s Resource solution. There
they have a common interface called “Resource” which is implemented by every-
thing from FileSystemResource to InputStreamResource. If were to im-
plement such an interface, a solution could simply be:

Properties p = new Properties();
//void loadFromXML(Resource xmlResource)
p.loadFromXML(new File(“.MyProps.xml”));

In this case the user of the API doesn’t have to think about in what way the XML
will be read; just that it will be read.

Think of logical mapping

The methods of a class (name and responsibility) must map well to the classes
name; input and output of a method must map the responsibility of the method and
so on. If this is done, the user will be able to use the API intuitively, and learn and
understand how to use it without any documentation.

//Bad mapping in Calendar
void setTime(Date date)
//Better mapping
void setTime(Time time)

Limit the number of options

If you have something in your API that can be done in two different ways, choose
one. Don’t give the user an ambiguous API with features that are so similar that it is
confusing, and force them to go to the documentation or choose by chance.

//...differs from...
// what way?

Avoid methods and classes that do
different things in different object states

Separate your domain entities in such a way that they overlap as little as possible.
This is basic OO and should be common sense, but it is a common problem. Java.
io.File has exactly this problem. An object of can be a File or a Directory.
If the object is created from the path of a directory it is a directory. This gives the
possibility to write, among other things, the following illogical code:

File myFile = new File(“.MyFile.xml”);
boolean dirMade = myFile.mkDir();

A better solution would be if File were structured something like:

interface FileSystemElement extends Resource{
class abstract AbstractFileSystemElement implements FileSystemElement{

class File extends AbstractFileSystemElement{

class Directory extends AbstractFileSystemElement{


The most important thing to remember is that there is a human user at the other
end of an API. If you remember this you will create better APIs. The pointers in this
article simply scratch the surface of what could be done to improve your APIs. One
thing that would result in great improvements is if you found a couple of users and
user-tested the solution. (

Originally published in JayView.

Leave a Reply