Like any product, APIs and client apps that use APIs have their own lifecycles. They each experience their own Create, Publish, Realize, Maintain, and Retire phases. When things go well, services will experience important use (and re-use) and grow to maturity to provide significant contributions to your company’s performance. And client apps will use APIs that connect to one or more services and, in their own way, create their own cycle of growth and maturity to increase revenue and/or customer use in ways that also spells success for your organization.
Through all these cycles and phases, it is important to have the right governance strategy in place, too. And a key part of that strategy is to recognize that the rate of change and the growth/maturity curve for services and clients are often different. That means different tactics and techniques are needed to support their success.
For example, client updates often happen more frequently than service updates. This is especially true as the API matures over time. And changes on the service side are much more likely to disrupt your API ecosystem than changes on the client side. Also, in a diverse ecosystem where there are lots of providers and consumers, it is rare that both the client app and the service component are released in any coordinated way.
Companies that recognize these differences have an advantage over their peers in the industry. They can fine tune their governance model to best take advantage of the variances between service cycles and client cycles and that provide the competitive advantage needed to gain and maintain the lead in your marketplace.
API service providers
For back-end services, the initial design and early release phases usually experience significant breaking changes. Even when you have a healthy pre-release design thinking culture, there are times when your early prototypes will not catch important bugs or feature needs until the service is already getting steady use in production. Good governance models take this into account.
Frequent changes at the start
For example, when designing and implementing your customer onboarding service, you may find your initial production release failed to take into account some edge cases. Making these changes after the first release runs the risk of breaking any existing implementations. That adds new costs and delays before you can ramp up into the growth and maturity phases of your service.
But it doesn’t need to be that way.
Reducing disruption through capabilities
A key element in successful API programs is supporting provider API changes without causing service disruptions to existing API consumers. A reliable way to do this is to focus API design and implementation patterns on capabilities instead of data models. Example of sustainable capabilities are customer on-boarding, contract-review, and purchase-approval. These are business level functions that have a long lifetime, even if details on how to implement them change over time.
Examples of potentially problematic API design focus are the customer-data API or the product-list API. These are “things” typically governed by physical location and logical schema. Those aspects (location and schema) are much more likely to change over time than actions like on-boarding customers or approval purchases. And changes in location and schema are more likely to break existing API consumer applications already in production.
The GraphQL style of service implementation does just that. It exposes properties and actions to allow clients to make their own decisions on what the service returns. And that means services can change how they collect and store data independent of the way clients want to view and consume that same data.
Another way this can be accomplished is through the reliance on API-first implementation formats like the Application-Level Profile Semantics (ALPS) interface description language. By sharing only the list of capabilities and properties and letting each implementation decide on their own URLs and objects, services can make changes safely without causing costly production disruptions.
Fewer changes for mature services
Once a service gets past the initial realization phase where changes are more common, it can move into a growth and maturity phase where only minor changes are needed to maintain an optimal consumer experience while maximizing revenue and/or reducing operating costs. Ironically, it is during the “settling down” phase that a service will usually experience its most significant consumer growth and re-use. And, during the increasing re-use phase it is even more important that the service undergo no major changes in its shared capabilities.
While governance in the early stages of a service focus on implementation details that make it easy for services to change without breaking consumers, the control model for mature services needs to focus on reducing the number of changes that could cause negative impact on usage and growth of that service. That means slowing the pace of change, and carefully evaluating cost/benefit profile of suggested modifications. Often it makes more sense to simply create a new service with the new in-demand features. That preserves the stability of the existing services and allows for new growth in your organization’s capability profile.
So, lots of changes at the start and fewer changes as the service matures — all managed by focusing on publishing a stable set of capabilities instead of a fixed set of URLs, methods, and payloads. That’s a common lifecycle pattern for server-side providers.
That’s slightly different than the client apps that consume those server-side APIs.
API consumer clients
During early prototyping and beta testing of API consumer apps, use cases are refined, expanded, and sometimes even dropped completely from the sprint, which leads to frequent changes. However, things calm down relatively soon. The important thing to keep in mind is API consumers often go through an additional period of high change frequency once the underlying Provider APIs mature and settle in. This is added phase of rapid change can cause serious disruptions for API consumers and providers unless solid design and implementation practices are already in place. And, just as in the lifecycle for API providers, the key to success is to focus on a set of capabilities for API consumers.
Frequent changes at the start
Early in the lifecycle of API consumers, there are often quite a few changes for a variety of reasons. First, early prototypes and beta editions of API consumers usually result in new discoveries. Assumed use case scenarios get refined. Some new scenarios emerge through testing, and sometimes initial use cases get dropped from the current design sprint. These changes come rather quickly and it is important to have a design phase in your API consumer lifecycle that is geared toward responding to these early discoveries.
Eventually, the initial production release is complete and deployed. After some minor bug fixing, things usually settle down for a while. However, as the API gets more use, clever API consumers start finding new uses (and, thus, new use cases) for the provider API. That means the API consumer (client apps) can go through a series of updates quite apart from the API provider lifecycle. This is where the API consumer begins to realize intended value.
But it gets better (or worse, depending on your point of view) because new uses are not all the API consumers begin to discover. They also start to uncover use cases where the existing API provider may need to add new features or make adjustments to the workflow support for API consumers. As consumption goes up, so does the demand on the provider.
This “going back to the well” experience where API consumers keep asking providers for more features can result in costly re-writes for the API provider and start to erode both the ROI and usability of the API ecosystem. I’ve known companies that are constantly updating their exciting backend APIs to the point where very little stability or reliability is left in the API ecosystem — everything is in a constant state of change, disruption, and instability.
But, as you can guess, it doesn’t have to be this way.
Reducing friction through capabilities
Just as we discussed above when talking about API provider disruption — the use of a capabilities model (instead of a features model) can help you maintain API platform stability while you make needed changes in the system. You can adopt platform design choices that provide freedom to client developers without adding burdens to provider developers. Design choices like hypermedia-driven APIs to allow clients to customize workflows or query-style interfaces like Resource Description Framework (RDF) or GraphQL to give API consumers control control over the “shape” of the response providers return. You can also employ design-time description languages like Application-Level Profile Semantics (ALPS) to focus on the actual capability descriptions rather than focusing objects and resources. That allows you to narrow your control to the factors that cause friction — changes in use cases.
Increasing scenarios for mature clients
One of the reasons API ecosystems can become less stable over time is that changes in use cases cause too much disruption to both API consumers and providers. Ideally, you want the process of supporting new use cases to be isolated to your API consumer community. This is one of the key principles behind the “reuse” mantra. For many the value of reuse is when you can re-use the same provider-side components to support brand new consumer-side scenarios.
Another common reason the consumer side experiences more change than the provider side is that, over time, more/better/different client applications spring up to take advantage of the existing provider APIs. This is another kind of reuse — the kind that allows brand new clients to be created to support new scenarios. Often these are scenarios that API providers hadn’t thought of when they did their work. The ability to support new releases of new API consumers is a key ability that can increase the ROI on your API ecosystem.
Summary
Well-designed and built service APIs will last a long time. They need to continue to run healthy and happy even when API consumer apps change or when brand new not-yet-imagined consume apps are created. To do that, focus on the key capabilities of your APIs (onboarding-customers, tracking-shipments, managing-feedback, etc.) and allow implementation details like URLs and object models to be more fluid and less brittle over time.
You can need to recognize that, while the API provider lifecycle settles down over time allowing you to gain added value through limited changes, API consumer lifecycles work quite differently. API consumers will constantly learn new use cases and look for ways to speed change through the whole life of the client-side API.
If you have to re-write both the front- and back-end applications to add support for a new feature or use case, your API design and implementation process needs some work. Supporting client-side change without the need for provider-side redeployment is the key to improving your API ecosystems, stability, re-usability, and your business ROI.
To learn more about how APIs can help your organization’s digital strategy, check out the MuleSoft API Strategy Hub.