The Engine of Application State

Aligning HATEOAS, Affordances and Business Events within an API-led Multi-modal Interoperability Framework

TRGoodwill
API Central
10 min readAug 16, 2022

--

HATEOAS, Affordance and Business Event State Transition Alignment

Introduction

The Richardson Maturity Model and Web API Design (Amundsen) Maturity Model are highly regarded models of API maturity. The most mature tier of each of these models, as per Fielding’s original vision, enshrine a vision in which application state transitions are driven purely by contextual affordances provided via hypermedia links. Moreover, services have unfettered control over their own namespace, and instruct clients on how to address relevant operations in real-time — only the root URI need be known to a client.

Implementation Challenges in a Large Enterprise

The vision is indeed compelling; however we must temper the dream with practical considerations:

  • There is a level of misalignment between HATEOAS and a specification-first approach to API management that must be addressed.
  • HATEOAS and dedicated affordances are architectural ‘features’ that come with development and maintenance costs. They should be business driven and employ an evolvable, minimum-viable design.
  • APIs do not exist in a vacuum. Affordance and HATEOAS implementation must be consistent across the enterprise and within a multi-modal interoperability framework.

The following discussion will attempt to narrow the broad sweep of the Richardson and Amundsen maturity models and suggest tactics to improve their fit for the contemporary enterprise context.

HATEOAS

API Maturity in the Richardson Maturity Model is measured in terms of the adoption of various elements of the RESTful technology stack. Richardson’s definition of Level 2 is focused on correct and consistent use of HTTP verbs and HTTP response codes. Level 3 maturity encompasses support for HATEOAS (Hypertext As The Engine Of Application State), and is the pinnacle of the Richardson Maturity Model.

The Richardson Maturity Model (restfulapi.net)

HATEOAS is a powerful concept that that is frequently addressed summarily by enterprise API guidance without any discernible purpose other than to check an API maturity checkbox and to claim conformance to sacred REST imperatives handed down by venerated sages. It is occasionally implemented perfunctorily and aimlessly. The prospect of deriving value from HATEOAS will improve with clear intent, minimum-viable scope and simplicity of implementation.

API Discovery

Realization of HATEOAS as the primary mechanism for navigating web services and real-time programmatic discovery of APIs is relatively uncommon. API discovery by application developers in a large enterprise is today largely facilitated by the all-conquering OpenAPI specification and API management platforms that require developers to on-board their systems and to subscribe to and test fully documented APIs.

SwaggerHub Developer Experience

The API management platform is effectively a management channel, and intentionally out-of-band (outside of real-time messaging). In this context, any aspect of the interface contract not fully documented in the API specification is back-channel and unmanageable.

This is not the future that Roy Fielding wanted for us, yet here we are. Given this constraint, we are prevented from providing absolute freedom to business services to control their own namespace from a base URI entry-point, and so we must recover a degree of freedom with modelling, documentation and version management conventions that do not constrain the evolution of state-lifecycle affordance operations, and with an efficient process to deploy changes to the domain model via a pipeline from our domain modelling tooling.

Documenting Discoverable HATEOAS Operations

In a specification-first managed API environment, HATEOAS link names and paths should correspond to a documented operation with an explicitly defined request and response document. HATEOAS links might be keyed to an operationId (undoubtedly the simplest mechanism) or to an OAS 3 link name. OAS links make explicit the relationship and traversal mechanism between operations.

For example:

Key to the OAS links value proposition is the rendering of links in swagger UI (and other OAS UIs), a feature not yet realised but on the horizon. The feature will make links and associated transition affordances more easily discoverable and comprehensible.

Takeaway: When published to an API management capability, every API operation applicable to a resource must be documented in the API specification — client developers will explore APIs this way.

HATEOAS Scope and Format

There are severe limitations concerning the utility of fully qualified, cross-resource HATEOAS links in an API Management framework that both embeds the API version in the URL, and requires subscription to APIs — both of which are common practice for a number of reasons. In this context, HATEOAS links would ideally identify only applicable affordances and/or sub-resources that occupy the same (versioned) namespace. If cross-linking is unavoidable, it must be managed as an end-to-end dependency.

Comprehensive HATEOAS schemes following HTML link syntax with rel, type and href attributes (such as HAL/RFC 5988) were designed to enable the provision of invocation metadata and breadcrumb discoverability that are redundant in a managed API context. Such schemes are thus unnecessarily verbose, affecting both the size and readability of the payload, as well as the clarity of the API specification. A simple object syntax that lists link literals by name and value, as advocated by JSON:API specification and employed by the Open Banking standard (and emerging energy and telecommunications standards) is preferable.

For example:

Takeaway: Use links to indicate applicable documented state-transition operations and sub-resources. Use the most efficient format that suites the use-case, and limit the scope to a single namespace.

Affordances

The Web API Design (Amundsen) Maturity Model focuses on data model abstraction. The pinnacle of the Amundsen model is when an API transcends resource centricity to offer affordances to the specific actions and subsets of data applicable to specific use-cases, focusing on “actions over data”. Affordances might include actions such as ‘search’, ‘suspend’, but would also include field selection, aggregation, conditional filtering, etc.

Mike Amundsen: Web API Design Maturity Model

Care must be taken in the interpretation of this model. Improperly conceived, an API that proliferates specific use-case affordances is liable to convolute or displace, rather than evolve the business resource — negating the decoupling qualities of the resource-centric approach, specifically its inherent stability, generality, and natural synthesis into a coherent enterprise federated data platform.

‘Action’ operations, should not replace HTTP verbs arbitrarily. When a process or transformation is the natural responsibility of an entity or value object, transparent HTTP verbs and HTTP response codes should apply to the business resource instance, unless significant complexity dictates otherwise.

‘Command’ Affordances

The first consideration around ‘command’ (usually state-transition) affordances is the question of whether the action should rather be driven by an asynchronous business event. For example, a shipment triggered by a payment event. This approach offers the highest degree of decoupling. Event-based triggers are not always applicable however, for instance in a real-time synchronous user-based interaction, when a client system requires a receipt or Id from the action, or when dealing with legacy or proprietary systems.

Synchronous and Asynchronous Driven State Transition

Synchronous affordances are always modeled as verbs that describe the action in the context of a resource instance, or resource collection. Link values will be a relative URI with absolute path — gateway hosting particulars should not be the server’s concern.

For example:

Takeaway: Operations should be consistently addressed as verbs that act in a resource context so that the intent of the affordance and its context are clear

‘Read’ Affordances

Not every client system will be interested in all of the information provided by a business resource API — even if it is modeled around core business data and streamlined for composability. A predictably implemented parameter and/or HTTP QUERY driven ‘read’ affordance model that includes field and collection filters can reduce over-fetching and enhance composability — without risking a proliferation of client-coupled response document models.

Query parameters commonly employed for this purpose include ‘fields’, ‘include’ and ‘sort’ parameters and field-based filtering. The exact name and syntax of the parameters matters less than the imperative that they are transparent in intent, and applied to a business resource context.

For example:

When supported end-to-end, the cacheable, idempotent HTTP QUERY method with well articulated standardized syntax and semantics (covering, among other things, logic operators) may be applied transparently to a business resource to enable more complex queries, and to encapsulate PII. In the absence of HTTP QUERY method support, a POST to a functional endpoint for an encapsulated query might be provided. e.g.

This is not to say that there is no place for explicit, optimised use-case read affordances — there will occasionally be an obvious, common, high-traffic use-case requirement that suggests such an affordance. Parameter-driven read affordance invocation pattens may in fact reveal such use-cases. What is important is that these affordances are generic, and not tightly coupled to the niche requirements of a specific client. e.g.

Takeaway: Employ a convention-over-configuration parameter-driven approach to provide flexible read affordances to improve composability without closely coupling business services to their clients.

Interoperability

Harmonized Models

Complex multi-model integrations are inherently difficult to comprehend and manage. Coordinating REST API, affordance, HATEOAS and business event models around the same authoritative domain model simplifies development, specification, discovery and comprehension. In a harmonized interoperability framework the domain model captures not only operational entities and value objects, but also the state lifecycle.

Domain data model and State-lifecycle diagram. Image by permission, Jargon.sh

From the state-lifecycle definition, and using the ubiquitous language of the domain, business events and triggers, state transition affordances and HATEOAS links are derived.

The Domain Model captures the REST data model, affordances, HATEOAS links and business events

Takeaway: Business events, state-transition affordances and HATEOAS links are derived from and align with the same state-lifecycle model and use the ubiquitous language of the domain to describe transitions.

Focused Implementation

A focused, minimum-viable pattern for HATEOAS will help identify valid use-cases and enable broader application. In a minimum-viable implementation as part of a harmonized framework, HATEOAS links are not a medium of discovery, but are employed to indicate the subset of state-lifecycle transition affordances applicable to a resource in its current state, and in the current invocation context.

The flow is predictable and tightly aligned with the domain state-lifecycle model:

  1. The resource response document will represent the current state of the resource instance and present valid links for transitions to adjacent states.
  2. Each HATEOAS link is keyed to a documented state-lifecycle transition affordance operation.
  3. Successful invocation of the affordance would result in a state transition and a published business event.
  4. Where valid state-transitions change, HATEOAS links returned with the REST resource will change accordingly.
Alignment of HATEOAS, State Transition Affordances and Business Events

Takeaway: In a focussed and minimum-viable implementation pattern, HATEOAS links are aligned with documented affordance operations and represent valid state transitions in the current context.

Vertically Integrated DevOps

HATEOAS as originally conceived is in part about giving a business services control over, and flexibility within its own namespace. When our API management strategy dictates published, self-contained API specifications, application on-boarding and API subscription, then we have inevitably lost some of the flexibility and control promised by the hypermedia vision and need to rebalance without compromising the strengths inherent in an API management capability.

Vertically Integrated DevOps will enable new and updated REST interfaces generated by domain modelling tooling and implemented by a business service to be published to API management platforms simultaneously with the deployment of business services with a minimum of friction.

API specifications and event config are produced by a collaborative modelling platform, validated and tested by integration and deployment automation, and deployed simultaneously with the business service

Robust agile planning practices as well as strong semantic version management and client communication conventions will help to minimise constraints to the evolution of state-lifecycles. The usual caveats apply — the addition of affordance operations, HATEOAS and OAS 3 links, response document fields and optional request document fields are non-breaking. The removal of operations and addition of mandatory input fields are breaking changes. API analytics will help development teams identify service consumers that are likely to be impacted by changes to state-lifecycles.

Takeaway: Integration and deployment of non-breaking API changes must be automated, domain-autonomous and as frictionless as possible.

Summing Up

The Richardson Maturity Model and Web API Design (Amundsen) Maturity Model focus on HATEOAS and dedicated use-case affordances; architectural features that may in some cases conflict with contemporary API management practices. In an enterprise environment in which an API Management capability is a given, reliance on these maturity models alone, as worthy as they are, can lead to inconsistent guidance, impede discoverability, and leave important challenges unaddressed. A managed API interoperability maturity model is discussed here.

An enterprise managed API capability based on an API specification standard introduces constraints on HATEOAS and affordance implementation, however a focused, minimum-viable pattern for HATEOAS and affordance implementation will ensure robust interoperability, help identify valid use-cases and enable broader application.

--

--

TRGoodwill
API Central

Tim has several years experience in the delivery and evolution of interoperability frameworks and platforms, and currently works out of Berlin for Accenture ASG