Your Comprehensive Web API Design Checklist

admin
#API | Posted

A Web API (Application Programming Interface) is a web application that’s not visual. There are no colors, layouts, or user interactions in the typical sense. Instead, there is the bare-bones request and response of structured data that facilitates everything from mobile apps to email notifications to stock trading.

Building a Web API is mostly a typical web software project: it’s got a variety of stakeholders both technical and non-technical, it’s got scope creep and feature dreams. What it lacks is an easy way to show intentions and progress to people that cannot read code. API design provides an opportunity to put something on a whiteboard and talk about what you are planning to build.

API DESIGN IS THE COUNTERPART OF VISUAL DESIGN IN THIS MACHINE-READABLE WORLD”

API design is the counterpart of visual design in this machine-readable world, a phase of work that starts between architectural planning and implementation where the details are defined. In this case, it’s a series of details in data handling in one of the most pitfall-laden categories of functionality in software: integrations.

System-to-system communications (or integrations) are not always pretty, but they are at the heart of many of the most important systems we see on the web today. Government, Education, Business, Humanitarian Aid, and Social Media are all increasingly driven by API platforms, and enriched at the point where two or more systems combine their content and services into a new and greater whole.

Putting the two sides of an integration together takes careful communications, planning for troubleshooting, and often the need to satisfy the process and technical needs of two different  teams for any single connection. For a public platform, that might translate to satisfying hundreds or thousands of development teams. How can you support the disparate technical requirements of all these API customers without having to interface with each individually?

Whether supporting one customer or many, your API Design should create intuitive, flexible access to functionality and data without being limited by any specific layout, use case, or medium. Other products bring their specific goals and lean on your API to realize them. Achieving this requires a design that is as close to a complete specification as possible, a document which ultimately is shared with your developer community.

Let’s imagine you’ve drafted your design specification. Before you can call it complete, what are the things you should make sure are done?

10 Points of Good API Design

1. KEEP IT SIMPLE

Maximum simplicity to satisfy business needs is the hallmark of any good technical plan, and an API design is no different. There are three different categories of complexity in an API: variety of options and structure in the data, richness of the data you suppose to provide, and tricky sequencing or workflows in request and response patterns. There are plenty of other sources for complexity in a webservice, but these are the core problems in the design of the API interface.

Variety of options and data structure can be curtailed with the simple question: did you keep the number of structural variations minimal? Every way of shaping a URL, querystring variable, request payload, or response payload is another thing to learn, test, and debug. A common feature in Content APIs the ability to request which fields should be included in a response, but this creates wide variety in the data. Variations are a source of rapidly growing complexity and can introduce performance issues because caching becomes less effective.

Rich data, emerging from elaborate structure definitions or semantic enhancement of the content, can be tremendously powerful in making integrations and data mining more intelligent. It also adds burden on the pace of API development and a greater dependency on support from content teams. Work with content experts to make sure the data you need is a maintained part of the system and not an “enhancement” added by the API layer.

Our last category of confusion is multi-step interactions. Are the workflows in your design simple? Commerce and authentication often require complex sequences of requests and authorization checks in order to complete a transaction, but multiple steps introduce a series of points of failure. Public or proven standards can go a long way to help smooth out the design and implementation, but there remains plenty of potential for miscommunication, bugs, and security holes. Invention in API workflows should only be done by necessity.

2. STANDARDS COMPLIANT

Does the design specify a violation of HTTP, RDF, JSON, TCP? Have you defined a schema (data structure) that closely matches an existing standard? Well-understood standards are an effective means to speed up developer understanding of your API, and provide dividends in collaboration on documentation, libraries, & tools.

If you are shooting for an API that is at least somewhat ReSTful (and you should be!) are you correctly using HTTP methods for most of your actions and Paths (resources) for the domain objects in your system? The words “save”, “create”, or “read” in the URL is a sign that something is wrong.

3. CONSISTENT AND INTUITIVE NAMING

Are words, labels, and pluralizations used consistently across your URLs and other structures? Are some of your names very similar in spelling or meaning such that they might be easily confused? The faster a developer can intuitively grasp or even memorize your API, the less time they will need to spend in the documentation trying to become productive again.

I use plurals for resource names to convey that a path without an ID will return a collection (or list) of resources.

Request

Response

animals

Alligator

Flamingo

Seahorse

animals/11

Alligator

 

4. CORRECT RESPONSE CODES

Every Web API response should have a correct HTTP status code. This is often forgotten but is especially critical to help developers troubleshoot their code. Websites are usually limited to around half-a-dozen of these status codes because there’s simply not much gain from them compared to adding messages to the page, but for APIs a dozen or more codes, carefully used, are a very useful attention to detail.

Some APIs define new codes or slightly reinterpret existing codes for their use. Twitter invented 429 Too Many Requests to clarify when a request is denied because the application making the request had reached a rate limit, and needs to lay off the API server for a cool-down period. Deletion is often a space where designers vary handling for a variety of specific concerns, all without violating the HTTP specification. (200 OK or 204 No Content to delete something; 403 Forbidden, 404 Not Found, or 410 Gone for later requests for the deleted item.)

For example:

  • Retrieve an item with GET: 200 OK

  • Create an item with POST: 201 Created

  • Syntax error in request: 400 Bad Request

  • Failed to authenticate request: 401 Unauthorized

As you delve into the 400 Bad Request response code, you may want to start exploring the idea of providing specific explanations of why the request went wrong and maybe an application-specific error code or documentation URL for easy research. Error responses have many of the same usability concerns as form validation errors–it is incredibly frustrating for developers to be told something is “wrong” without a reason why. If you want to follow an existing standard (see point #2) check out the API Problem Details RFC.

5. CACHING DIRECTIVES FOR ALL RESOURCES

All systems on the web from the server to the browser pay close attention to caching instructions. This guidance is what determines whether data needs to be downloaded fresh each time a page loads, and avoiding the need to download again is one of the secrets to good web performance.

Every API resource should declare its own caching rules with the correct HTTP caching headers. This might be key to operational scale for the API so caching proxies, browsers, and effective integrations to keep requests across the web to a minimum and run as smoothly as possible.

Even if nothing that consumes the API can be expected to respect your caching rules, they remain an effective way to communicate expected freshness and utility of the data. Your API is clearly announcing it’s not a real-time, continuously updated data feed if it’s caching headers announce 1 week expirations, or even an hour.

1

cache-control: max-age=3600

If this item leaves you with more questions about how HTTP caching works, I recommend you check out Ilya Grigorik’s awesome HTTP Caching article.

6. DISCOVERABLE

Does your API have “landing resources” to guide new API integrators to the documentation, key endpoints, licensing and versioning information, and everything else they might need? Do your resources link with nice URLs to all the related things in the system? Links to the author, to view revisions, to the canonical “webpage” are all useful to have.

Here’s a “pseudo-code” example of an API Landing Resource to illustrate the idea.

  1. {
  2.   links: {
  3.     self: "http://api.example.com",
  4.     website: "https://example.com",
  5.     documentation: "https://dev.example.com",
  6.     tos: "https://dev.example.com/tos",
  7.   }
  8.   resources: {
  9.     users: "/v1/users",
  10.     content: "/v1/content"
  11.   },
  12.   version: 1
  13. }

API Design is a flexible discipline, and you have the opportunity to drop plenty of signposts into your API responses to provide all the context a developer needs to successfully explore what they need to know without extensive cross-referencing of identifiers and content sources. I think of this as “pragmatic hypermedia”, a partial use of the more technically thorough implications of custom MIME-types, code generation, and distributed API mesh networks that are included at the higher end of hypermedia discussion. Pragmatic hypermedia is a powerful benefit for people in the same way hyperlinks help webpages.

PRAGMATIC HYPERMEDIA IS A POWERFUL BENEFIT FOR PEOPLE”

A good litmus test of whether you’ve been thorough enough would be to hand a tech-savvy co-worker a mysterious URL and see if they can make useful API requests, read the documentation, and maybe write a blog post about some of the awesome functionality you’ve built. Did they find everything?

7. NO OUT OF BAND KNOWLEDGE

It’s easy when building on a framework that provides a lot of rich functionality to take the easy approach to API implementation: converting the internal variables and data structures of the system to JSON and sending it out over the wire. This is a bad practice, as many of those internal details are confusing or irrelevant to API consumers, not the lean, domain-specific data properties they are looking to use.

Taking some examples of Drupal data structures we try to clean up from our Drupal-based APIs,

  • What’s an nid or vid?

  • Why do some properties get prefixed with field_ and others do not?

  • What does sticky mean?

These are all very familiar to a Drupal developer, but developers integrating the API may never have looked at Drupal documentation before, let alone code, and shouldn’t need to understand it to use your API.

Even worse, if you build your API on systems without a filter in between, it’s really easy for unrelated functionality changes to disrupt your API’s responses. Any change to your API that’s not made deliberately could be a breaking change, a violation of backwards compatibility, for all the applications integrated with your API. A successful API should evolve without creating more work for others, and a public API that goes through this kind of unpredictable change can destroy the fledgling trust of a newly forming developer community.

8. FORWARD COMPATIBILITY & EXTENSIBILITY

Speaking of backwards compatibility, the best way to ensure your design isn’t headed towards breaking changes is to plan on Forward Compatibility and Extensibility. Can you anticipate specific changes in the future? Plan for them in your design now. Is some content in your API likely to shift from single to multiple instances of a specific field? For example, a User Profile API should be designed to allow folks to refer to more than one phone number, child, or vehicle.

BAD

GOOD

1
2
3

{
  "car": "Orange Sedan"
}

1
2
3
4
5
6

{
  cars: [
    "Orange Sedan",
    "Gray Coupe"
  ]
}

Your API is a contract, build the expectation of change into it.

9. COMPLETELY DOCUMENTED

Assumptions can be costly when trying to align disparate teams around a new API design. Could someone else implement the API with minimal discussion? The design hasn’t been fully written down unless multiple people could code against the standard before a reference implementation exists.There are many tools that can facilitate this kind of documentation, such as Swagger, RAML, and Blueprint, and one day we’ll talk about them in greater depth.

If your API includes complex workflows such as a custom implementation of oAuth, be sure to include sequence diagrams to ensure the flow of requests is well-understood. There are a number of free online tools to create these diagrams, such as http://www.ckwnc.com/.

Screen-Shot-2015-06-01-at-9.45.17-AM

10. PEER REVIEWED

Your API design should be a high value document that clearly explains all the necessary details. Make sure other people can understand the specification, and that they think critically about the implications for scalability and data access that it implies. API design can have implications of scale and performance that may not be supportable by the systems that will back the new webservice. For example, if access to a resource is contingent on approval from a subscriptions database that has only ever been access by a handful of people via a simple application, is that database prepared to respond to hundreds or thousands of queries per day?

Peer review is also an opportunity for other people to point out the holes in the specification early, before developers make a mix of assumptions about the design intent.

Mocking Your Design

Even a complete API specification can be confusing to people without a lot of careful study. This is where examples can come in really handy, and if you’ve included them in your document that is fantastic. If you haven’t you may want to finish off your design work by mocking some resources that can serve as a live demonstration of your API.

Your mocked API resources can serve as an initial reference implementation to convey a greater sense for others of the practical meaning of the specification. Beyond that, developers waiting to consume the API can use a mocked service for initial steps of their work.

Even better, a well-mocked service is real enough that you can use normal testing tools and validators to confirm things like standards compliance. For example, point redbot.org or a JSON validator at your mocked resources.

Keep Learning!

API Design can seem like a dry subject, but it’s at the intersection of new ways of solving problems, new kinds of tooling to communicate with and empower non-technical people, and the leading edge of web standards development. Embrace it as an opportunity to engage with people across the boundaries of technology and business.

Interested in learning more about sophisticated API-driven platforms? Read up on how the Phase2 team transformed data into knowledge by developing a humanitarian API for ReliefWeb, or subscribe to our newsletter to keep up with new projects and blogs from the Phase2 team!

admin