Designing good APIs is a difficult task with a lot of subjective metrics. Even a small startup that has fully-embraced...
RESTful API design principles and has a complete view of their problem space can end up with inconsistent naming, obscure interfaces and undocumented semantics. When a large organization with many different development teams confronts these same challenges in an ad hoc manner, the effects are compounded and often result in APIs sinking into silos from which it is difficult for them to emerge. In this article, I will discuss three practices that will help your enterprise APIs avoid these pitfalls.
Getting semantics right
The most important thing to get right is semantics. That word gets used very loosely, but here I mean the naming of API endpoints and querystring parameters, the layout of passed data structures, the use of HTTP headers, and the conventions around returning HTTP status codes. Different designers often interpret the basic principles of RESTful (representational state transfer) interfaces from quite different points of view, and the quality of the interpretation ends up being very subjective. This is most acutely true in the naming of endpoints and the use of parameters and data structures.
API endpoint names are the most visible aspect of an API that consumers encounter, and communicate more to the consumer about the RESTful API design than any other feature. Whether an endpoint is named for a resource (customer), a process (inventory) or even a medium (mobile), the API will be more comprehensible if the convention is applied consistently across the problem space and the business. In a large enterprise the only way to achieve that level of consistency is to have strong conventions that are agreed-on and applied routinely across all development teams. Getting to that ideal is an exercise in management, just as much as it is a design effort.
Beyond API endpoint naming, you have the issue of naming parameters and data structures. Different interfaces will have different data needs, but style conventions should be adopted and used here as well. If "OneAPIDoesThis" and "another_does_this," the APIs taken together are less comprehensible. The same thing applies to common parameters or common data structures. If two endpoints take an access token, then it's generally going to be better if they use the same name for it. To get some good pointers on API naming conventions and how to apply them, look to major players like Netflix or Twitter for guidelines.
Discovery and documentation
Even if you have good RESTful API design and consistently applied conventions, they will be of little benefit to consumers of your API if they can't easily learn about those design features and explore the ways that different endpoints are used. Fortunately, we have Swagger, one of my favorite tools for API design and testing, and the first tool I reach for when designing a new API once I get past the initial conceptualization phase.
Swagger is, at heart, a specification for describing a RESTful API in a structured way, using either JSON or YAML as a markup language. Clustered around this specification are a set of tools for editing the markup and generating free stuff: stubs, endpoint tests and also good HTML documentation. There are two aspects of Swagger that I find particularly useful. The first is that, since it is markup, the specification of your API can be made the return type of a special "self-documentation" endpoint, often named Swagger. Consumers can use this endpoint to quickly access the structured specification of your API.
The second thing I love about Swagger is model validation. As part of the process of documenting an API, you define the data structures that your endpoint returns as a model type. You can document fields, whether they are required or optional, as well as value ranges and constraints. Having done this, you can use libraries like bravado-core to validate incoming data against the model specifications at runtime, returning detailed error information when validation fails. This saves a ton of work, and gives very high assurance that your code is operating on valid input.
Access and testability
One of the early barriers that consumers encounter when starting with a new API is figuring out how it works. However well named the endpoints are, or how available the documentation, most developers need to test an API as part of the early development process for a new client. Easily, my favorite tool for API testing is a Chrome browser extension named Postman. Postman allows you to define named collections of endpoints, along with the URLs, querystring parameters, headers and body data needed to execute each one. Once defined, an endpoint can be executed with a single click, and reports back on the performance of the call as well as giving access to detailed information about the response.
Once a collection is defined, it can be distributed to consumers for their own use in a couple of ways: One is to upload it to the Postman servers, a process that returns a URL clients can access to pull it back down. The collection can also be exported as JSON and served off an endpoint on your own servers, a preferable alternative if the API is not public. I often use the endpoint and Postman for this purpose. This is another area where Swagger can help, since Postman can import a Swagger specification and generate an endpoint collection for you. It doesn't get much easier than that.
There are many other important design and implementation considerations when developing a new API, of course. One of the most impactful is how you decide to do version control on it, a topic deep enough to deserve an article of its own. For now, I believe that following the practices outlined above will help you create APIs that are consistent across your business, discoverable by consumers and self-documenting on-demand, and easily testable by client developers. Taken together, these are three ways to help stave off the chaos of enterprise API management.
Looking to the future of RESTful API design
Security needs in RESTful API design
Object storage needs for RESTful APIs