It is not the strongest of the species that survive, nor the most intelligent, but the one most responsive to change. – Charles Darwin
I saw a really cool “Rube Goldberg-esque” IoT (Internet of Things) demonstration at Gluecon this year by Kirsten Hunter. She strung together a health tracking reward solution by making use of a Fitbit to monitor physical activity, MyFitnessPal to track nutritional intake, Twillio to send SMS nags and a smart phone integration to a Philips Hue Light bulb to indicate progress against goals through the day by change in color. It was all tied together in a codeless faction with IFTTT. In theory, an API-accessible freezer lock could have allowed access to her Ben and Jerry’s once she met defined goals for the day.
Rube would have been proud. How cool is it that we can compose these separate things into a solution – all through well-defined, exposed APIs?
You may not appreciate just how exciting this new reality is if you have not been wandering the desolate wastelands of Lego-like componentization aspirations as many of us in the industry. The ability to leverage a uniform interface across an open transport is indeed powerful and will continue to transform our business and lives for the foreseeable future.
As exciting as this is , that capability still does not come for free. You cannot magically generate successful REST (or even HTTP-based) APIs for all to use except for the most elementary of systems or for those that were already well modularized and componentized. While it is perfectly reasonable to create facades onto complex, monolithic systems or use other adaptor techniques to get APIs into the market, bolting on APIs will not transform your existing system into the evolvable and sustainable set of capabilities required to pivot and support your emergent markets once you open the gates – if you can even “bolt” anything on.
I introduced the multi-style, API-centric architecture as one option to gain the benefits of externally exposed APIs while also providing for functional evolution and technical scalability.
Figure 1 Utility Principle with Multi-style API-centric Architecture
This representation is an architectural model – meaning that it is technology and implementation independent. The goal is to highlight important concerns learned from component and service-oriented styles to help you organize your system.
As such, the layers representing those concerns are meant to address specific problems, provide an organizational frame and create a common language. They are not meant to encourage sprawl of business logic across the layers. Cohesion and encapsulation are serious design drivers - poor alignment will result in arrested evolution and painful maintenance. Concepts such as Smart Endpoints and Dumb Pipes should also be considered, but you must pragmatically factor those considerations in your problem space. In my case, I am considering a multi-tenant application platform with multiple technical channels that expects lots of regulatory and feature enhancements in a shifting market as well as continued traffic growth.
This model shares some of the same intents as Cockburn’s Hexagonal Architecture- the application should be driven by many actors and devices, not just a UI, and it has taken a fully API-centric approach for all interaction. By retaining a layered model, I can emphasize the desired outcomes of managing high utility at the core while pushing increasing degrees of variation, such as technical adaptors (or even trading partner specific variations), closer to the edge to promote evolution, flexibility and testability. I may take the translation of this into a visual hexagonal architecture in the future, but for now, this model allows me to demonstrate a second dimension of componentization (and, later, a third for addressing execution architectural qualities).
While this is a technology neutral diagram, I have made a few assumptions for my purposes that lean toward specific implementations:
- The only style of access across the system is via remote APIs (except for inevitable adaptors to external partners which are not supported by APIs)
- The API is resource-centric and RESTful – at least HTTP-based to leverage HTTP (of the internet) as much as possible to avoid extraneous middleware
Before we dive in, we must also consider these concepts and imposed constraints to set context:
- This model is divided across consumers and producers of resources to distinguish basic responsibilities
- Consumers and providers only communicate via APIs
- The API layers are sandwiched between two potential points of external access:
- applications (composite/composed applications), and
- core resources
- The API layers are propped up by crosscutting supporting concerns for management and governance
- API-centricity must be embraced across the entire platform and product offerings to get the most benefit from adoption – in other words, maturity of implementations across the “consumers” and the “resource providers” must be coordinated and relative constraints due to low maturity understood to avoid suboptimal outcomes
- Composition is incumbent of API-centricity – it is expected that:
- APIs are composable
- ALL “applications” are a composition of APIs, including data access
- Applications are created with facilities that can aggregate and orchestrate APIs as needed, potentially across multiple sources and security contexts, such as well-known web “mash-up apps”
Now we can dig into our model to better understand the intent and value of each concern.
Figure 2 Multi-style API-centric Architecture
Consumer Concerns: Made up of both external and internal constituent components, including some API handling:
- External Consumers - all external constituents that access the platform in all forms of access including direct user access to web and mobile user experiences as well as system access via API from client systems, partner systems and other third-party developers.
- Goal: ensure we understand all our constituents and their data exchange needs, with a focus on API
- Internal Consumers - all internal constituents including web experiences service via the Composite Web Apps, Mobile App support, internal administrative experience and even traditional data exchange styles (ahem, files) – all of these examples are viewed as compositions of APIs.
- Goal: define boundaries, responsibilities, data exchange styles and domains required by our internal constituents and proxies
Resource Provider Concerns: Made up of all internal and external resources (via resource interaction), including some API handling
- API Edge / Access (OK, this is implementation specific, but useful – thanks George Box) – manages inevitable network edge idiosyncrasies, load balancing, smart routing and a point of indirection to responsively handle variable client needs – using HTTP where possible. Supported/part of API Governance; defined in API Management. Note that many implementation options exist including not only standalone components, but embedding in smart endpoints as well.
- Goal: isolate network edge support, provide common facilities to enhance HTTP capabilities where necessary and provide injection of API Governance & Management
- Composite API - similar to the Composite App capabilities - it is a direct sibling in some respects. It represents the ability to expose an orchestration or composing application as an API. There are additional considerations concerning API chaining that must be considered and is a topic in and of itself.
- Goal: encapsulate common orchestrations/processes and aggregations rather than exposing complexity to the end-consuming system; transformations for specialization to clients can be provide, but must be treated as a composite app at that point to avoid unintended sprawl of logic
- Application API - manages the direct exposure of a resource representation from/near the resource– the most native exposure of an API. For monolithic systems, they are the facades into the system and deployment scope is constrained to that “execution space”. These are the remote interfaces for microservices.
- Goal: define boundaries and responsibilities around remote access to resources; encapsulate common API provisioning conventions and capabilities
- Resources - collection of all resources including microservice units, monolithic cores, legacy applications and data-oriented resources (may also be encapsulated as microservices).
- Goal: keep the resources isolated and nurtured so they can evolve as needed.
- External Resource Adaptor - similar to and on the same level as the internal Resources, but acting as a proxy to External Resources such as client and partner systems
- Goal: surface external resource access on the same standard as internal resources where and when required
- Component Layer - virtualized layer to represent modular design and creation of software components INDEPENDENT of the remote interface with the intent to survive changes in access technologies (REST today, gone tomorrow). This organization can occur within a monolithic system or as separate artifacts.
- Goal: create defined and well-bounded software components
Crosscutting Supporting Concerns: Made up of all capabilities required to manage and support the system across concerns and throughout the full lifecycle
- API Governance - runtime governance support of API – edge capabilities, authentication, security policy support, utilization policy support, routing, monitoring/tracking, etc
- Goal: enforce and monitor API policies
- API Management - lifecycle management support of API – portals, authoring/designer support, catalogs, analytics, product management support, etc
- Goal: support full API lifecycle including Use, Create and Manage perspectives.
Just a Model
The ability to create new solutions in a codeless fashion by accessing readily available components via a uniform interface across an open transport with REST APIs is very cool and will change our businesses and lives for the foreseeable future. However, participating in that world by offering your resources is not so straightforward and can lead to a catastrophe without proper organization. You need an architectural blueprint to ensure there is a tomorrow. This model is one example of how you can organize your concerns to not only get to tomorrow, but to thrive.