4 Areas of Consistency for Great Developer Experience Posted in Design Kristopher Sandoval December 24, 2020 Few things harm an API quite like inconsistency. Inconsistency within an API ecosystem can frustrate and confuse even the most experienced power users, creating a perpetuating cycle of failed calls and incorrect assumptions. While it’s seldom considered as its own problem, often being lumped in by type (such as unclear error codes), the reality is that inconsistency creates more inconsistency — if one aspect of an API suffers from this, the rest is likely to as well. Below are some specific API design areas where inconsistency is common. We’ll consider the implications of things like inconsistent endpoint naming, variable error codes, and spotty documentation, and see how we can instead build more intuitive developer experiences. 1. Naming and Endpoint Consistency One of the most common consistency issues in many modern API instances also happens to be the most encompassing — name consistency. Name issues cover a few domains, but inconsistency across the board can cause significant problems regardless of where that inconsistency lives for a broad range of users. Let’s take a look at two possible domains where this inconsistency can be a problem. Clarity For a public API, one of the development goals should be that the API is easily understood. While this understanding is typically gained through ample documentation or other educational efforts, endpoint naming is often overlooked as a profound opportunity to express purpose and intent. How endpoints are named and how descriptive they are can significantly impact how the average user understands what they’re interfacing with. Imagine you are developing an API that remotely serves the weather to a user. When considering a collection of endpoints, imagine two extremes. On one side, we have an obscure version: https://weatherapi.nordicapis.com/aqi10 https://weatherapi.nordicapis.com/tmplcl https://weatherapi.nordicapis.com/usrlclctyid These endpoints are pretty incomprehensible. They may represent shorthand for internal function names, yet the average external developer would likely have absolutely no idea what they do. Perhaps they can infer a possible function, but not the whole purpose. Instead, let’s rename these endpoints to be more understandable: https://weatherapi.nordicapis.com/airqualityindex https://weatherapi.nordicapis.com/localtemperature https://weatherapi.nordicapis.com/setusercity For the average end-user, this change could be so monumental that it unlocks understanding around the entire API, increasing self-service capabilities. Casing Additionally, if a casing style is used, it should be consistent across all endpoints. CamelCase (in which each new word is capitalized, e.g., AirQualityIndex or airQualityIndex), Snake Case (where underscores replace spaces, e.g., Air_Quality_Index), and other approaches are acceptable. Still, it should be considered a best practice to keep this style consistent. For example, if one endpoint is AirQualityIndex, you should not also have an instance of set_User-City. Small variances like this, over the breadth of a service, can ultimately result in higher complexity and less understanding. Accuracy Related to endpoint clarity is the relative accuracy of each endpoint. It’s not enough to ensure that the endpoint is named consistently; you must also ensure that it does what it says it does. Incompatibilities often arise after multiple revisions and variations on the core codebase, especially if it is old or depends on other libraries. For instance, let’s expand the imagined weather API example. Our users are requesting more functionality. One function has to do with integrating into calendar applications to provide a snapshot of the week’s weather alongside scheduled activities. As you develop, you discover that one of the endpoints, https://weatherapi.nordicapis.com/weeklyweather, does not, in fact, serve the weather in a grouping for the week, but provides average weekly temperature and precipitation. Such unclear naming can cause significant problems for both developers and users. For developers, especially those who did not work on the core codebase, assumptions based around named functionality can result in non-functional applications. Some endpoints can be relatively understandable, such as the example given above, while others can be less understandable. Something like https://weatherapi.nordicapis.com/time could imply so many functions behind it (local time, GMT-specific time, regional time, etc.) that it’s simply too unclear to be helpful. 2. API Design Paradigm The API design style chosen by a provider is essential, but being consistent with it is even more critical. It is not unheard of that an API adopts a paradigm based upon the solution de jure but follows that choice poorly. APIs that claim to be RESTful sometimes don’t follow a core tenant of RESTful design, GraphQL APIs may not allow truly transformative requests from users, and so on. This is not only true of paradigm misalignments, either. Sometimes the paradigm is followed, yet the internal API ecosystem is incoherent or confusing. An API may push other requests to other internal APIs, and often, these APIs could be strangely grouped (for instance, an API that handles media transformation may also manage user accounts). In a RESTful paradigm, it’s not just enough to be RESTful — you must also be RESTful and coherent across all the APIs. It’s also important to know when not to be RESTful, when to leverage other options, and most importantly, when to separate a monolithic API into microservices (or vice versa). Ultimately, it doesn’t matter what paradigm you use — if you are RESTful, be RESTful. If you use SOAP, follow SOAP, but above all else, be consistent. Utilizing an internal style guide (like the ones in API Stylebook) can help ensure and enforce this consistency. If you’re going to use a guide like this, you should insist on it and use it. Again, above all else, be consistent. 3. Error Handling One point of clarity that is often missed is in error handling. Too often, error handling is dealt with by serving general error codes with no additional information. How many times has a service returned an error that simply says “sorry, this resource is not found”? For the end-user, this experience is not only ineffective; it’s frustrating. Errors should be handled consistently, given a specific form and function. One of the best resources for standardizing error handling is using standard HTTP status codes. This is a great solution, as each type of error code is delineated and understandable simply by knowing what category these codes fall in. The standard codes are noted below: 1xx — these codes deliver information, typically to confirm receipt of the request. 2xx – 200 — this spectrum of codes notes that a request was received, understood, and accepted. 3xx — this band of codes notes a redirection condition and can be a tip-off that the initial request, while once accurate, is no longer the proper method. 4xx — these denote client errors, indicating bad syntax or some other error. 5xx — these denote server errors from an otherwise valid request. Standardizing behind these code ranges and serving the correct codes each time consistently can dramatically increase the API’s accuracy, efficacy, and functionality and the average user flow. The key aspect here is to ensure consistency — user errors should be client-centric, server-errors should be in the 5xx range, etc. 4. Documentation Documentation should never be considered an afterthought — consistency is extremely important for quality documentation. So what does this mean in practice? First, ensure that your documentation is accurate. At a basic level, documentation must reflect the actual functions, endpoints, and facets of the API in great detail. Documentation should always match production —it is this consistency that lends itself to accuracy, and thus to good documentation. Secondly, navigation is a vital, often overlooked aspect. It’s not just enough to have accurate documentation — developers must be able to navigate it. One way to increase consistency here is to think of your documentation from a scientific point of view. Break everything first down by topics, then by functions, variations, and finally examples. The specific structure doesn’t need to be exact — what is most important is that if you adopt a format, stick with it. Finally, content should be efficient. Consider the average developer consumer — do they have time to read for an hour to understand one function? Of course not – they depend on brevity, examples, and efficacy. Be brief, concise, and accurate. Conclusion Inconsistency across an API can drive inefficiency, confusion, and failure. With all of this in mind, the solution is simple — be consistent. Even if you adopt your own standards for style, naming, error codes, etc., be uniform across your developer platform. As long as everything is done in a consistent manner, even proprietary solutions can be quickly learned and understood within the context of the rest of the body of work. As long as any inconsistency exists, the API will forever be lacking clarification, which decreases usability and self-service capabilities. Do you think we are overstating the importance of consistency? Is there another facet that is arguably more important? Let us know in the comments below!