The first article in this series went over the importance of an organization knowing its goals, one of four factors...
that play a critical role when designing APIs. This article covers the second factor: knowing consumers. Did you know there are strict height and weight requirements for fighter pilots? With the G-forces involved and the advanced technology, it would not be cost-effective to design an interface that could work for both a 5-foot-2-inch 140-pound person and a 6-foot-5-inch 300-pound person.
The same is true for application programming interfaces (APIs). Although no one wants to turn away potential API consumers in the way the military might tell an aspiring pilot they're not a good fit, it's still true that the broader the range of consumers and capabilities supported, the larger the investment.
Let's start with the basics, which involve simply answering one question: What actions are consumers trying to perform?
As simple as this sounds, it's a frequently misunderstood or is a missed step. It's easy to get caught up in how a service accomplishes something versus what needs to be achieved. A consumer shouldn't know about an organization's internal database structures or whether the API is provided by a legacy system, packaged application, or a node.js program.
First and foremost, it's important to think from a consumer's point of view and understand what actions they might need to perform. In their book, A Practical Approach to API Design, authors D. Keith Casey Jr. and James Higginbotham devote a chapter to designing beyond CRUD (Create, Read, Update, and Delete). By thinking in terms of actions and goals the consumer wants to achieve, the focus can be on what the consumer wants to accomplish rather than on how the API provider will accomplish the task.
A focus on actions tends to bring things into common English terms and can assist in getting things into a verb-noun structure, such as provision a server or place an order. The important thing is to clearly understand the resources (information) and actions needed for the consumer to achieve goals. Don't immediately think an action-based approach will lead to SOAP services with its distributed-object roots. Understanding consumers is an analysis task whose only goal is to provide the information needed to make solid API design decisions.
Casey and Higginbotham do move beyond CRUD in their book, putting an emphasis on understanding the interactions a consumer must take to reach objectives. A goal like placing an order sounds simple, but a number of activities must happen before the order can be placed, and the API needs to support all of them. This is where the real challenge lies in API design, because most companies don't have an "API for everything" policy like Amazon does. Let's face it, when dealing with an internal-only environment, there are more ways to get API design wrong than right. This leads to a major piece of advice: Design an API as if all consumers are external.
Why is this so critical? An internal environment makes it too easy to take shortcuts. Sometimes those shortcuts are justified, but every shortcut has a hidden cost. Shortcuts usually mean giving up abstraction, resulting in more tightly coupled systems. This raises the bar for entry for anyone new. So, by thinking externally first, better APIs will be created.
- Justify every element: Question all attributes placed in the API. Does that information really need to leave the firewall? Does that consumer really need to specify all of those parameters to make this work?
- No shortcuts: External systems can't access any other systems unless they're exposed via APIs. In internal integration scenarios, it's far too easy to take a shortcut because a consuming system already had access to some other piece of data. This can lead to poorly abstracted services and APIs that are unusable for new consumers.
- No baggage: An external customer isn't going to care whether a service has a mainframe backing it, Java code on an app server, or a node.js script. And frankly, customers should call an organization out if the API design makes those things apparent.
- Usability: In an internal environment, it's easy to make up for poor API design and documentation by talking to someone. It's not as simple for someone outside a company to do the same thing. External APIs must be well-documented and easily understood.
Another point to consider: Are consumers paying for API access? Customers who are explicitly paying introduces a whole new dynamic. The more they pay, the more influence they are likely to have. Explicit payment includes pay-per-use, subscription-based access, and customized APIs. Implicit payment means consumers are getting access to the service as a result of some other contractual agreement, but are not billed.
Contrary to popular belief, it's probably easier to get to a solid interface when a customer is explicitly paying for access. In the implicit case, the consumer has already paid the bill and is going to be resistant to anything that might make their information more difficult. In any paid case, it needs to be determined whether all customers are created equally. Will API customization be performed for someone willing to pay more?
Finally, consumers will certainly have bearing on what technologies are used to expose APIs. Supporting browser-based and mobile-based consumers has different dynamics than supporting legacy internal consumers. The former may lead towards REST-based services with an HTTP-based interface, likely leveraging JSON and possibly XML for the message payloads. The latter may lead to legacy integration approaches.
About the author:
Todd Biske is an enterprise architect with a Fortune 50 company in the St. Louis metro area. He has had architecture experience in many different verticals, including healthcare, financial services, publishing and manufacturing, over the course of his 20-year career.