Tighten Evolution Strategy
also known as: Increase Lifetime Guarantee, Strengthen/Stretch Lifetime Commitment
Context and Motivation
An API runs in production. Its compatibility and extensibility characteristics are expressed in the form of one or more evolution patterns, including Experimental Preview, Aggressive Obsolescence, Limited Lifetime Guarantee, and Two in Production. These patterns differ in the way and the frequency the provider is able to introduce breaking changes.1
As an API provider, I want to expand and extend the lifetime, stability, and support guarantees of an API endpoint with its elements (operations, messages) so that existing and new clients can use the API longer.
Stakeholder Concerns
- #maintainability
- During their lifetimes, API versions have to be supported and evolved. Security patches are applied, bugs are fixed, and so on. The effort for such activities might not be proportional to the guaranteed lifetime but certainly is related and somewhat coupled to it. Related (sub-)concerns are compatibility and extensibility.
- #cost
- Effort comes with cost. Operational and capital expenditure, including budget for training, evolution (including documentation), and operations increase as lifetime guarantees are extended.
- #flexibility
- The more lifetime guarantees are given and the longer the committed time spans are, the less freedom remains with respect to changing product vision and corresponding API designs (for instance, the role of an API in the organization).
According to “Interface Evolution Patterns — Balancing Compatibility and Extensibility across Service Life Cycles”, evolution patterns are confronted with desired qualities such as:
- Enhancing compatibility and developer experience
- Allowing the provider and the client to follow different life cycles, e.g., a provider can roll out a new API version without breaking existing clients
- Minimizing changes to the client forced by API changes
- Making it possible for the provider to improve and extend the API and change it to accommodate new requirements
- Guaranteeing that API changes do not lead to semantic ‘misunderstandings’ between client and provider
- Minimizing the maintenance effort to support old clients [Lübke et al. 2019]
Initial Position Sketch
The following provider specification does not yet define any life cycle guarantee (notation: MDSL):
API provider SampleAPIProvider1
offers SomeDemoContract
at endpoint location "http://www.testdomain.io:80/path/subpath"
via protocol HTTP binding resource SampleAPIProvider1Resource
Clients are not clear about what they can expect from the provider:
Tighten Evolution Strategy: Initial Position Sketch
This “refactoring”2 targets API endpoints and their API Descriptions (including business and technical contract between a provider and its clients). It may also affect any Service Level Agreement (SLA) that accompanies or is part of such an API Description.
Design Smells
- Lack of trust and confidence
- Client developers decide not to use the API because it comes across as unstable and subject to change often (or disappear).
- Client community smaller than expected
- The provider receives less client traffic than expected and hoped for. Client feedback indicates that the API functionality is appreciated, but API usage is not considered a viable design option due to missing stability and support guarantees.
Instructions
The following transitions and combinations of evolution patterns to increase guarantees make sense:
- Upgrade from no guarantee to Experimental Preview.
- Transition from Experimental Preview to Aggressive Obsolescence.
- Become more assertive and switch from Aggressive Obsolescence to Limited Lifetime Guarantee.
- Change from any other life cycle pattern to Two In Production.
- Refine from Two In Production to its N in Production variant (with N equal to or greater than three).
Target Solution Sketch (Evolution Outline)
The life cycle guarantee is not an architectural element but a documentation item first and foremost.
Tighten Evolution Strategy: Target Solution Sketch
Some Interface Definition Languages (IDLs) have dedicated support for such Metadata Elements (for instance, OpenAPI and MDSL); in other documentation formats, lifecycle and version information usually goes into more general description fields or comments.
Example(s)
When applying this refactoring, an MDSL contract changes from:
API provider SampleAPIProvider1 version 1.0.0
offers SomeDemoContract
at endpoint location "http://www.testdomain.io:80/path/subpath"
via protocol HTTP
binding
resource SampleAPIProvider1Resource
provider governance AGGRESSIVE_OBSOLESCENCE
to:
API provider SampleAPIProvider1 version 2.0.0
offers SomeDemoContract
at endpoint location "http://www.testdomain.io:80/path/subpath"
via protocol HTTP
binding
resource SampleAPIProvider1Resource
provider governance LIMITED_LIFETIME_GUARANTEE
The Evolution Patterns on the MAP website feature real-world known uses of the patterns (and their introduction over time).
Hints and Pitfalls to Avoid
Apply this refactoring when existing clients complain, for instance about a lack of planning horizon and effort to catch up with API updates.
When applying the refactoring, perform a cost-benefit analysis. Communicate changes early, clearly, and continuously. Minimize incompatible changes and apply Semantic Versioning when releasing.
Do not over-commit but find a balance between conflicting concerns, for instance those of external stakeholders and those of the API development team.
Related Content
This refactoring is the opposite of Relax Evolution Strategy.
Introduce Version Mediator can be applied if lifetime guarantees are weakened and some clients are unable to migrate to a newer, incompatible version. And Introduce Version Identifier might have to be applied before this one so that clients can learn about versions and their (in-)compatibilities.
MDSL specifications have an optional SLA section and a provider governance
element in the API provider part. This is explained on the MDSL website.
References
Lübke, Daniel, Olaf Zimmermann, Cesare Pautasso, Uwe Zdun, and Mirko Stocker. 2019. “Interface Evolution Patterns: Balancing Compatibility and Extensibility Across Service Life Cycles.” In Proceedings of the 24th European Conference on Pattern Languages of Programs. EuroPLop ’19. New York, NY, USA: Association for Computing Machinery. https://doi.org/10.1145/3361149.3361164.
-
Alternatively (but only justified in rare cases), the provider might decide not to do so at all and guarantee an Eternal Lifetime Guarantee. ↩
-
We use double quotes here because this design tactic actually does not change the API structure, but a quality property of it. Note that tightening is the opposite of relaxing; a reverse “refactoring” Relax Evolution Strategy exists as well. ↩