Web API Design & Evolution (WADE)
Local vs. Remote Interfaces - Design Guidelines, Notations, Patterns
Application Programming Interfaces (APIs) have been around for a long time, both program-internal (local) ones and remote APIs connecting processes and systems across networks. In recent years, API design and management have become an important topic acknowledged by analysts (see for instance Gartner's strategic technology trend no. 8 for 2017, mesh app and service architecture) and vendors (see for instance this blog).
APIs are required to realize microservices and to practice distributed Domain-Driven Design. They often are part of a DevOps approach: an API needs to be developed and operated along with its provider implementations, but certain APIs can also act as enablers for DevOps initiatives (e.g., APIs used for automated provisioning and distributed log analysis). Thousands of Web APIs exist today, and more are being built. The ProgrammableWeb directory lists many of them.
Quality Attributes for APIs ("APIlity")
- APIs should meet the performance and availability requirements that have been stated for them in a specific and measurable way; preferably, the rationale for their design should be made explicit to ease their consumability, but also API evolution and maintenance (see here for some related method guidance).
- APIs should be consumable for developers and their app(lication)s
- APIs should be extensible and be able to evolve, preferably without breaking existing clients (backward compatibility)
POINT Principles for API Design
General architectural principles and patterns are eligible for API design, but additional, API-specific ones exist as well. For remote APIs, the fallacies of distributed computing come into play (although some might say these fallacies are no longer relevant in the cloud age; see for example this opinion).
To get its job done, a remote API should get (and stick) to its POINTs:
- P – an API must be purposeful (i.e., driven by the information need of its clients and their use cases/user stories). This principle is also called design-by-intent sometimes. Many APIs serve multiple clients; others are specialized for a particular one (Sam Newman calls the latter approach backends for frontends).
- O – an API should expose domain objects in the form and concept mandated by the chosen architectural style and integration technology (e.g., resources in RESTful HTTP or WSD/SOAP Web services) and should adhere to Software Engineering (SE) and Object-Oriented (OO) principles such as high cohesion/low coupling. There should be one and only one way to execute a use case or user story to make the API lean.
- I – each API call should be as isolated as possible (i.e., free of unexpected, undesired side effects); statelessness helps with that, as well as specifying pre- and postconditions. This principle corresponds to the I in an IDEAL cloud application architecture (see this OOP presentation or this presentation).
- N – an API should be neutral, i.e. not optimized for any particular client and/or channel (unless this is its very purpose and it is supported by neutral backend services/APIs).
- T – an API should be T-shaped (i.e., offer broad and deep calls); it may be organized according to the master-details metaphor and/or provide search-and-iterate-through-results functionality.
To get to the POINT, consider to:
- Follow a recognized analysis and design method to identify API call candidates and flesh out their invocation syntax.
- Amend each call and/or entire endpoint with an SLA that contains one more more quantified SLOs.
- Define an API lifecycle management policy that balances agility and stability
- Five "golden rules" for Web API design are listed and discussed here: "Documentation, Stability and Consistency, Flexibility, Security, Ease of Adoption".
Most pattern languages focus on design and architecture of API implementations and (SOA) infrastructure rather than the actual APIs and service message content; Service Design Patterns is an exception and the Conversation Patterns touch upon message content too.
Enter: Microservice API Patterns (MAP)
Our Microservices API Patterns (MAP), first workshopped at EuroPLOP 2017 and extended continuously since then, focus exclusively on message design (rather than service infrastructures or implementations):
- Structural interface representation patterns: Pagination, Atomic Parameter List, Parameter Tree; Id Element, Entity Element, Metadata Element; final paper available in the ACM Digital Library and authors copy (free PDF) available here
- Quality patterns. 5 workshopped at EuroPLOP 2018: Service Level Agreement, API Key, Rate Limit, Rate Plan, Wish List (authors copy of published paper); more to come: e.g., Request Bundle, Error Reporting
- Evolution patterns: e.g. Version Identifier, Semantic Versioning, Two in Production, Aggressive Obsolescence, Experimental Preview (discussed in Writer's Workshop at EuroPLoP 2019; published paper)
- Responsibility patterns: e.g. Master Data Holder, Linked Information Holder, Embedded Entity; State Transition Operation, Computation Function, Retrieval Operation (EuroPLoP 2020: Processing Resource and Operation Responsibilities paper, Information Holders paper)
Best Practices Presentations and Articles
- There is a topic tag to identify API design articles in Martin Fowler's bliki
- For local APIs, J. Bloch has a rich set of advice to give in his articles and presentations
- For Web APIs, see for instance Subbu Allamaraju's recipes in his RESTful HTTP Cookbook
API Contract Management Notations
- RAML and Swagger, emerged into OpenAPI Specification
- JSON API and APIs.json (note: similar names, but different efforts and scopes!)
- UML profiles for SOA, USDL
- WADL for (RESTFul) HTTP resources
- WSDL for SOAP services