Improve your API Design with 7 Guiding Principles
In the mid-1990s, Jakob Nielsen and Rolf Molich created a set of design principles for evaluating and measuring the usability of an interface. Their “10 Usability Heuristics for User Interface Design” highlighted areas that designers needed to focus on if they wanted better usability in their products.
If you’re an API designer, the heuristics are worth learning. The principles that Nielsen and Molich laid out are still relevant today and give you a great base for building usability thinking. By working through each heuristic, you will start thinking critically about your API and how you can improve it.
To help you along your way, I’ve whittled the original list down to the seven heuristics that are the most important for API designers to learn and understand:
1. Visibility of System Status
“The system should always keep users informed about what is going on, through appropriate feedback within reasonable time.” — Nielsen
In a graphical user interface, users can easily get confused when the system doesn’t provide relevant feedback. For example, pressing a button and not getting any response from the UI would leave a user wondering if the button was correctly pushed. Timely and relevant information needs to be provided to the user for this heuristic to be met.
This kind of information access is important for APIs as well. Increased system status visibility can help developers who write the client applications that use an API. Providing more and better information about the system will help developers understand what has happened when they invoke the API, leading to a better development experience.
But, providing system status visibility doesn’t mean dumping all available information about the innards of our system. From a client developer perspective, the system of concern is the interface, not the underlying database or code. It’s important for a client to know that a call may take a long time to complete, but learning that a call is slow because of a specific database configuration is interesting, but not terribly useful.
For HTTP APIs, the response status code provides a good, basic level of system status information. For example, the 2xx series informs a caller that things went well, while the 4xx and 5xx series indicates some type of failure. Picking specific status codes such as 202 or 404 can give additional system status information. But, designers can go beyond the HTTP level codes and provides additional system status information in their message bodies, incorporating problem details and the current state of resources that may have been changed. Increasing the fidelity of system status information should increase the usability of the API.
When evaluating APIs, look for cases where a lack of status visibility makes the act of writing the client more difficult.
- Is it difficult to learn when something has gone wrong in the system?
- Does the interface tell us the result of invocations and requests?
- Should the system describe any relevant side-effects that may have occurred?
2. Match Between the System and the Real World
“The system should speak the users’ language, with words, phrases and concepts familiar to the user, rather than system-oriented terms. Follow real-world conventions, making information appear in a natural and logical order.” — Nielsen
User-friendliness is rooted in building an interface that matches the user’s model of the world — the goal is to reduce the number of new things that a user will need to learn. Interfaces that feel familiar are easier to learn and use.
When it comes to API usability, the user we care about is the developer who is writing the code that will use our interface. This means that the language, patterns and conventions of the API should match its user’s world as closely as possible. That world includes the tools and programming languages that they use to write code, the industry and organizations they work within and the community and social world they live in.
An API evaluator will need to start by identifying the target user of the API. If no user profile is available, then a generic developer will need to be defined. Identify the parts of the API that would cause unnecessary cognitive load (or “friction”) for the user. This may be a result of words that are unfamiliar, semantics (meanings of words) that would conflict with the user’s understanding and message formats or message patterns that don’t fit the developer’s world perspective.
- Do the message formats, libraries and message patterns match the user’s world?
- Is the vocabulary of the API a good match for the user?
- Does the API act like the APIs that users are used to using?
3. Consistency and Standards
“Users should not have to wonder whether different words, situations, or actions mean the same thing.” — Nielsen
Consistency is an important part of interface design — changing the rules for how something works is an unpleasant surprise and can lead to frustration. The cost of interface inconsistency is especially high in the API design space, where every inconsistency leads to more code being written to handle those one-off edge cases. This type of usability bug can really hurt the API developer experience.
Learning how to use an API really means learning the rules for using the interface. That includes every part of the API, from the message format and query parameters of the interface to the presentation style of the documentation. Every API design decision that you make establishes a rule that your users will learn.
When evaluating an API, look for cases where the user would be surprised by the way a particular part of the interface works because it breaks a convention that has been established elsewhere in the design. Also, identify cases where the API unnecessarily breaks with popular conventions in the industry.
- Is the API consistent in its signature (e.g. URI format, query controls)?
- Is the vocabulary of the API consistent? Do words have the same meaning everywhere?
- Is the documentation and support tooling consistent across all parts of the API? Does the runtime behavior match the documented behavior?
4. Error Prevention
“Even better than good error messages is a careful design which prevents a problem from occurring in the first place.” — Nielsen
For an API, errors include problems that happen during client development (syntax errors, typos and misunderstood meanings) as well as errors that happen after the client is developed and published (unexpected data and changes that break the application). The usability of the API is greatly improved if we can prevent every type of error from occurring.
Error prevention is a big problem space, but when reviewing an API you can look for these types of issues in particular:
- Are documented examples incorrect or misleading?
- Is the API designed in a way that makes it “brittle” — where changes to the interface can easily break the application?
- Is the design overly complex? Are there opportunities to simplify the cognitive workload of the user?
5. Flexibility and Efficiency of Use
“Accelerators — unseen by the novice user — may often speed up the interaction for the expert user such that the system can cater to both inexperienced and experienced users. Allow users to tailor frequent actions.” — Nielsen
An interface that provides flexibility, helps cater to different types of users who may have similar needs but are working within different contexts. The classic example that Neilsen and Molich provide is the case of accelerators — for example, a GUI application that provides keyboard shortcuts for regularly used interactions. The first time you copy and paste you might use a menu system, but if that remains the only option, the 50th copy and paste operation will be very frustrating.
An API that offers flexibility and efficiency of use should provide an interface that is easy to use for the beginner, along with optional controls aimed at improving efficiency. That improvement could come from users having to write less code if they know what they are doing, or from run-time applications making less API calls when the interface is used in some custom fashion.
Examples of this at work in APIs include: supporting multiple API styles and formats, offering condensed or paginated response data and providing controls that allow client applications to customize the responses they receive.
When evaluating an API for flexibility and efficiency, consider the different types of users that will use it.
- How suitable is the interface for the first-time user?
- Does the API provide controls and shortcuts for more advanced and experienced users? Are defaults used for special controls?
- Are there opportunities to optimize any repetitive or unnecessary steps?
6. Help Users Recognize, Diagnose, and Recover from Errors
“Error messages should be expressed in plain language (no codes), precisely indicate the problem, and constructively suggest a solution.” — Nielsen
API error messages have two audiences:
- The machine-driven client application that acts programmatically on what it receives
- The human developer responsible for writing applications that use the API
The usability of an API depends on both the machine and human audience’s needs being met.
When describing this heuristic, Neilsen warns us specifically not to use “codes” in error messages. But, in the API space it makes sense to ignore this advice — at least when it comes to our runtime-machine based users. Easily parseable error codes perfectly fit the needs of a client program that must make decisions based on runtime conditions.
But, an API that offers high levels of usability should also include error information that pertains to the human audience. This means providing human-readable text that describes the error condition and offers advice on troubleshooting.
Evaluators should look carefully at the error information provided by an API.
- Is error information correct?
- Is machine readable information provided?
- Does it describe the error in a way that the human use can understand it?
- Is enough information provided to correct the error?
7. Help and Documentation
“Even though it is better if the system can be used without documentation, it may be necessary to provide help and documentation. Any such information should be easy to search, focused on the user’s task, list concrete steps to be carried out, and not be too large.” — Nielsen
From a human interaction perspective, API documentation is that main interface through which the developer interacts with your interface. Even if the documentation acts only as a starting point from which the API’s users will learn through invocation, it is a necessary part of the experience.
API documentation can be evaluated in the same manner as any piece of technical writing. Reviewers should pay attention to the style, content and architecture of the information provided.
- Does the documentation address the needs of different learning stages (beginner, intermediate and expert?)
- How much documentation needs to be read before a call can be made? Are examples provided in the docs?
- How well does the documentation structure map to the problems that a user will try to solve?
Using the Heuristics to Improve Your API Design
The original ten usability heuristics were meant to be used as part of an interface evaluation method. As Jakob Nielsen described in 1995, the idea was to gather a small group of design experts and have them look for usability bugs using the defined design principles. While it’s not as effective as getting feedback from actual users, it’s a nice, economical way of identifying usability problems early.
But, even if you don’t adopt a formal heuristic evaluation with experts, simply having your peers (or even just yourself) review an API based on Nielsen and Molich’s set of heuristics can be enlightening. If you find it valuable, you can extend or customize the list to highlight the parts of API usability you care the most about.
A big value in identifying heuristics comes from having a methodical, structured way to think and talk about the usability of your API. The hard work comes in taking action on the problems you discover and validating your hypotheses about good or bad usability when real users get their hands on your API.
Building easy to learn, easy to use APIs isn’t easy, but starting with a set of guiding principles as a first step can increase your chances of success.