APIs should get to the POINT

Doc SoC
Doc SoC
Mar 10 · 9 min read

This post proposes five principles for API design, summarized as POINT: purposeful, style-oriented, isolated, channel-neutral and T-shaped.

Context: Web API Design and Evolution (WADE)

Application Programming Interfaces (APIs) have been around for a long time, both local ones inside modular programs and remote APIs connecting operating system processes and distributed systems. Message-based protocols such as RESTful HTTP, gRPC and GraphQL dominate the remote API realm.

IMHO, any API, whether local or remote, should address an actual client information or integration need. When delivering related functionality, three types of quality attributes are particularly relevant:

  • Developmental qualities. APIs should be straightforward to learn and easily consumable for developers and their app(lication)s, collectively referred to as providing a positive Developer Experience (DX).
  • Operational qualities. APIs should meet the performance and reliability requirements that have been stated for them, including availability and API security.
  • Managerial qualities. APIs should be maintainable and evolvable over time, preferably being both extensible and backward compatible, so that changes are possible but do not break existing clients. Agility and stability have to be balanced here.

While we can probably agree on these quality goals as an API incarnation of the general Functionality, Usability, Reliability, Performance, Supportability (FURPS) taxonomy for (non-)functional requirements rather easily, how do we get a new API there? One way is to:

Establish API design principles as an intermediate step to drive and justify responsible decisions later (at the most responsible moment).

Getting local APIs right is one thing.[1] For remote APIs, the fallacies of distributed computing come into play; for instance, networks cannot be assumed to be reliable.[2]

Enter: Architectural Principles

Principles both qualify as requirements and design elements (and decisions about those). In his presentation “Using Software Architecture Principles in Practice”, Eoin Woods defines: “an architectural principle is a declarative statement made with the intention to guide architectural design decisions in order to achieve one or more qualities of a system”. I already listed some types of desired qualities in API design; related design decisions deal with number of endpoints, format and content of request and response messages, message exchange technologies, API versioning and so on.

Following Eoin’s definition, principles can guide quality goal-oriented decision making, constraining the solution space without imposing any particular design prematurely:

From Objectives to Patterns, Decisions, and Assets (Technologies, Products) via Principles

The loose coupling principle, for instance, applies to APIs and most other designs, as it makes the end-to-end system less brittle and its parts easier to evolve independently. Software engineering principles such as high cohesion and single responsibility per stakeholder can also guide the identification of API endpoints and the design of its operations. Such principles may be established on all responsibility levels, from entire organization (enterprise architecture) to programs and portfolios to individual teams and products.

POINT: Five Principles for API Design

Let’s try to identify some additional, API-specific principles now. I propose a remote API should get (and stick) to five POINTs by default to get its job done, meeting or exceeding the expectations of its clients:

  1. P — an API must be purposeful and driven by the information needs of its clients, expressed as use cases, user stories or similar. It should be straightforward to answer questions like “why and when would an API client program call this operation?” The number and flow of API calls required to satisfy the information needs should support the client-side data usage paths (for instance, the flows in a single-page application running in a Web browser or in a rich desktop client program).[3]
  2. O — an API should be oriented according to the form and concepts mandated by the chosen architectural style and integration technology (e.g., resources in RESTful HTTP or ports in WSDL/SOAP Web services); it may expose a view on domain objects via facades.[4]
  3. I — each API call should be as isolated as possible, i.e., be free of unexpected, undesired side effects. It should not interfere with calls to other operations in the same or other APIs. Statelessness helps with that; establishing adequate pre- and postconditions does so too.[5]
  4. N — an API should be channel-neutral, not be optimized solely for any particular stakeholder group and/or client technology such as Web applications (of various kinds) or rich clients (in mobile phones, on PCs). Typically APIs serve multiple clients, but this is not a must; several 1:1 customer-supplier relationships might be easier to manage than one open 1:n interface that pleases many, possibly diverging stakeholders. Some APIs specialize on a particular client technology, though; this might be the single actual purpose of an API.[6]
  5. T — an API should be T-shaped in its scope and offer broad and deep functionality; for instance, it may be organized according to the overview-details metaphor and support both search-and-iterate-through-results as well as direct-lookup-via-keys in its retrieval operations. It is possible to provide multiple Ts per API, or move the vertical bar of the T upon consumer demand.[7]

Can we be confident that POINT helps us achieve the qualities identified above? The P corresponds to the functionality-F in FURPS terms (introduced above), and a T-shape brings usability. The O promotes supportability, a managerial quality. I improves the API client developer experience and simplifies testing (another developmental quality); it also has a positive impact on consistency, scalability and reliability (operational qualities). N is good for supportability too. The five POINTs do not claim to be mutually exclusive or collectively exhaustive; feel free to add principles as needed.

Examples of POINT in Action

Cesare Pautasso and his team collected and visualized the URI-verb structure of 93 Web APIs in their e-book “Beautiful APIs”. You’ll find plenty of T-shaped APIs in it, for instance:

This resource path tree is part of the tvMaze user API, offering several Ts to inquire about followed people, shows, and Web channels as well as voted shows and episodes, both generally (collection resources, plural resource names) and individually (_id resources).

How to become POINTed?

To get to the POINT during API design, consider to:

  • Follow recognized analysis and design methods to identify API call candidates and flesh out their invocation syntax. The Design Practice Repository that I co-created collects elements from such methods.
  • Apply a pattern-oriented software (and API) architecture approach. See below for further hints.
  • When making design decisions, ask/evaluate whether the chosen option will promote or prevent P, O, I, N and/or T and include this criterion in your definition of done for architectural decisions. When not adhering to a principle, document why.
  • Once you have decided for a style orientation, make this evident in the names and structures of the operation messages and API endpoints.
  • Foresee one and only one way to execute a use case or user story implementation to make the API lean and easy to use, review and extend.[8]
  • Plan the API testing early and adjust the test plans and cases as the design evolves. Add some POINT “compliance checks” to the API testing.
  • Define an API lifecycle management policy that balances extensibility and backward compatibility. You also might want to review the API regularly.

Note: There might be good reasons to break a principle; for instance, empowering clients to come up with new Purposes for existing data implies that the eventual client needs can not be known upfront (see examples above). And a Backend-for-Frontend API deliberately will not be very Neutral.

Our Microservice API Patterns (MAP) relate to the five POINTs as well. With MAP, the journey from requirements to principles and patterns looks like this:

From FURPS qualities to Microservice API Patterns via POINT principles

Purpose comes from the application of responsibility patterns (and endpoint identification heuristics). As a pattern language, MAP is agnostic to style Orientation, but draws examples and known uses from REST. Several structural patterns such as Context Representation and some members of the quality patterns category address Isolation. Applying any patterns can help you be channel-Neutral. Both a single general-purpose API and multiple specialized ones require versioning and lifecycle management evolution patterns to become supportable. The right mix of role stereotypes and operation responsibilities yields T-shaped APIs.

What Do Others Say?

Blog Posts and Online Articles. Jordan Ambra presents “five golden rules” for Web API design: “Documentation, Stability and Consistency, Flexibility, Security, Ease of Adoption”.[9] Mathieu Fenniak’s API checklist has 43 entries (some of which are specific to HTTP and REST). James Higginbotham blogs here and here; he suggests job stories to articulate API purpose. You will find very valid POINTs in all of these sources.

Books and Patterns. Mike Amundsen features the P principle as the first section of API stories in “Design and Build Great Web APIs: Robust, Reliable, and Resilient”. API Handyman Arnaud Lauret devotes Chapter 2 of “The Design of Web APIs” to API goals; his API goal canvas establishes P(urpose). Arnaud also provides a handy API review checklist and many examples of good and bad (or more or less POINTed) API designs, touching on N and T.

“Service Design Patterns” by Rob Daigneau describes several styles that bring O(rientation). Erik Wilde suggests some patterns to achieve “Robust Extensibility”.

In “Cloud Strategy”, Gregor Hohpe positions principles to connect strategy and decisions and establishes two general ones “use before reuse” and “design from front-to-back” (P). Gregor then also establishes the FROSST principles: “Frugal, Relocatable, Observable, Seamlessly updatable, internally Secured, failure Tolerant” (I).[10]

Summary and Outlook

The take-away messages from this post are:

  • Quality goals for APIs come in three forms: developmental, operational and managerial. Note that such goals should be elicited (even in very agile settings); try SMART Non-Functional Requirements to do so.
  • General architectural principles and the API design-specific POINT criteria can guide the architectural decision making: purposeful, style-oriented, isolated from others, channel-neutral and T-shaped.
  • Applying the Microservice API Patterns and other practices increases the chances of meeting the principles. API testing helps to find out whether you succeeded.
  • Violating one or more principle is perfectly fine in certain contexts as long as this is a conscious decision and decision rationale is captured.[11]
  • Several books and numerous online articles on Web API design are available and send similar and/or complementary messages. Update (April 20, 2021): I am working on an ebook featuring many design practices, including stepwise service and API design.

I do not suggest a closed set of strict rules; the five POINT principles leave room for appropriate solution design and are extensible as well. Do you agree with them?

Please contact me if you have feedback or input. If you liked the article, please clap for it (and start following?).

Olaf (a.k.a. Doc SoC)

PS: An extended version of this post is in my blog The Concerned Architect.

Acknowledgements

I would like to thank my Microservice API Patterns (MAP) co-authors Mirko Stocker, Daniel Lübke, Cesare Pautasso, and Uwe Zdun for their POINTed feedback and input on our MAPs since late 2016. Oliver Kopp commented on an intermediate draft of this post, and Tammo van Lessen contributed via insightful discussions.

Notes

  1. See the InfoQ article “Bumper-Sticker API Design” by Joshua Bloch for advice how to design local APIs.
  2. Although some might say these fallacies are no longer relevant in the cloud age; see for example this opinion.
  3. This principle is also called design with intent or “domain functionality first, client next”.
  4. See Chapter 6 of the eBook “An Introduction to APIs” by Brian Cooksey for rationale.
  5. This principle corresponds to the I in an IDEAL cloud application architecture.
  6. Sam Newman calls such approach “Backends for Frontends”, frontend being technical user channels such as desktop client and mobile client. Such one-backend-per-user-experience set of APIs in turn should be supported by neutral backend (micro-)services exposed by a service layer and/or domain model implementation of the API functionality.
  7. The T metaphor became popular in a hiring and interviewing context; think of the API purpose (its P) as the skills of the API.
  8. Lots of alternative navigation paths and operations and many optional representation elements (payload data fields) might come across as user-friendly and client-oriented at first glance, but often cause much more time spend on learning and deciding which options to use (and then testing that valid choices have been made) than on actual client and provider development.
  9. Note that the rules, available here, blend design criteria with (partial) solutions and best practice recommendations.
  10. Self test: do the POINT principles adhere to the “Principles for Defining Principles” on page 33 of “Cloud Strategy”?
  11. Why decouple a JavaScript Web client from the server-side API provider implementation if these two are developed by the same team at the same time and then packaged and shipped in the same deployment unit?

© Olaf Zimmermann, 2021. All rights reserved.

ZIO’s Blog: Architectural Decisions, (Micro-)Services and More

Stories, insights, and unsolicited advice from 25+ years of software architecting.