In the intro to this blog series, I promised to reconcile the apparent incongruence of strategic business objectives (move fast) with traditional IT must have paradigms (be safe). In the last post, we chugged away at the surrounding ecosystem that’s needed to support the velocity promised by the former. In this post, I pause at the pre-production station to discuss some of those system safety properties that we can’t leave behind.
The pragmatic conductor
Take any CEO in any industry, and they will likely say that they have three primary goals:
An API program (including microservices) shouldn’t focus on technology, but rather how that technology should be applied to enable new capabilities that make an organization different from its competitors. Uber and Lyft, as case studies on industry disruption, didn’t succeed just because of the technology — their success stemmed more from providing amazing customer experiences in transportation enabled by technology. Jeff Bezos, too, knows that Amazon’s own demise will be the ultimate mea culpa of missed user expectations.
If we maniacally focus on the experiences, does that imply that we must dismiss the stability and efficiency long considered to be the pillars of IT management? Of course not, they too contribute to the user experience, but I offer this consideration — those capabilities should be put “on rails” so developers can focus on creating differentiated experiences rather than focus on the supporting infrastructure, environments, and tooling.
Guide rails providing safety during this journey
Rails offer stability at speed. Rails offer performance in harsh environments. Rails offer controls and security to minimize risk. Rails, as provided by a unified platform, can help achieve the promise of running microservices by allowing developers to focus on the things that make their organization unique. Rails are a pragmatic solution to the very complicated problem of scale. Anypoint Platform offers shared services across full lifecycle API development to help minimize the disruption that this new modern architecture could otherwise create.
In a modern architecture, traditional resiliency tactics (such as hot/cold standbys, over-provisioning, etc.) don’t really translate effectively. Microservice architectures consequentially become resilient when the designer adapts patterns and practices such as runtime isolation, component independence (such as classloading isolation), and building to fail (such as with transaction management and compensating transactions, error handling, etc). A service should be defensively implemented, and the platform should provide protection in the event of failure.
Additionally, not only should build and integration testing be automated during CI/CD pipelines, an organization should also automate destructive testing in production to test any combination of the following resiliency patterns and best practice recommendations:
- The circuit breaker pattern/sensible timeouts to fail fast on offense, but also to provide cached or default responses when necessary.
- Canary testing while evolving.
- The ability to concurrently support all data access patterns that surface data to APIs for real-time, stream, or batch data access requirements while maintaining bounded contexts and independent deployability.
- Message queuing, eventual consistency patterns, CQRS, event sourcing capabilities, and log-based architectures to rebuild state or other appropriate service consistency contingencies can be implemented.
- Best practices around the implementation of idempotent services where possible.
- Evolvable provider strategy to codify the contract of trust between API producer and consumer. “When people are building on top of our API, we’re really asking them to trust us with the time they’re investing in building their applications. And to earn that trust, we can’t make changes [to the API] that would cause their code to break.” – Jason Rudolph, GitHub (2013).
It probably hasn’t been lost on anyone that implementing microservices shouldn’t be about simplification or cost-cutting. However, IT should still seek to reduce that burden as best as they can. A platform should participate in reducing costs and complexity via many capabilities called out in the prerequisites section and others, namely:
- SDKs and accelerators and reusable assets (common services) across lifecycle (ideation to governance and management).
- A common platform to minimize talent scarcity by skill sharing across the entire API lifecycle.
- Automation, fitting into existing DevOps processes.
- Monitoring and service cross-cutting distributed logging across the application network graph.
- Scaling and scheduling in your cloud or ours.
MuleSoft’s API-led connectivity approach can be used to ensure stability, security, and operational efficiency in a microservice architecture as well as create agility in a diverse enterprise. Using well-defined, discoverable APIs can help to insulate change, and also to provide an interface to high-quality, productized microservices that are rapidly composable across mixed environments.
“The greatest leverage in systems architecting is at the interfaces… When the components of a system are highly independent, operationally and managerially, the architecture of the system is the interfaces… The components are outside the scope and control of an architect of the whole.”
In the next entry in this series, I offer a few more API considerations in North-South and East-West microservice communication, security, and integration patterns.