APIs which expose synchronous interactions can be classified into a set of types or 'implementation patterns'.
Recommended patterns are:
- Simple pass through
- Orchestration Façade
Patterns to use with caution include:
- Transformation Façade
- Wrapper Façade
Simple pass through
A single client HTTP request to the API Management proxy results in a single back-end target API call. The API will present data in the latest standard data model appropriate to the use case – FHIR R4 UK Core at the time of writing.
The API does not perform any mediation between on-the-wire data formats and does not orchestrate calls to other APIs.
The diagram below illustrates this:
One client HTTP request results in a single back-end target API request without any message transformation. The request is 'passed through' the API Management layer which applies, for example, standard security, logging and alerting.
Where there is a set of back-end API services exposing granular functionality or data sets, it can often be very beneficial from a consumer viewpoint to create a middleware API from these granular APIs. The façade API is then made available to consumers to meet a business use case more simply.
One API client HTTP request results in the middleware API making multiple HTTP requests to back-end service APIs. There is often a need to implement some form of business logic in this middleware API to orchestrate these back-end calls. This type of façade presents a simple synchronous API for consumption by API clients, while hiding from clients the complexity of multiple back-end services which are involved in servicing the request.
FHIR exchange paradigm
The strongly recommended means of exchanging data when synchronous interactions are used is to exchange UK Core resources using the FHIR http exchange paradigm. FHIR http expresses requests as Create/Read/Update/Delete (CRUD) operations upon resource endpoints which are exposed by an HTTP server.
Where the nature of the interaction is clearly the invocation of a business service, or the called function cannot be expressed easily as a granular CRUD operation, the Operations Framework extends FHIR http for these scenarios. These calls can be defined alongside Restful CRUD requests in the same API.
Where a back-end API has legacy characteristics, elements of the transformation or wrapper pattern would also be required.
Use of the orchestration façade pattern assumes that the primary focus is on production of granular pass-through APIs. These pass-through APIs continue to be consumable by API clients even though for certain use cases a client does not need to interact with them directly but may use an orchestration façade.
To hide granular pass-through APIs from consumers through construction of an orchestration layer could be considered an anti-pattern. It is normally better to provide API consumers with options - to consume granular APIs to meet granular data or functional needs, or to choose to use an orchestration façade to fulfil specific use cases.
A middleware layer is introduced which acts as a façade to a back-end API. The back-end API may be an existing API which uses a deprecated message format. This pattern enables the existing API to be used quickly while hiding legacy implementation details from the API client.
One client HTTP request results in a single back-end target API call, but this request is handled by an intermediary API. This middleware API mediates between a legacy or proprietary message format and a current standard. The API Management layer component is a proxy which applies standard security, monitoring other platform benefits.
You would use the transformation façade typically where you have an existing legacy API which you want to expose quickly for consumption in a way which meets current standards.
However, you should prefer the simple pass-through API over transformation façade patterns as this adds additional complexity solely to hide technical debt from the API consumer. As such, if there is no plan in place to address the technical debt present in the back-end service, this is an anti-pattern.
It is typically acceptable therefore to use this pattern to meet short term business objectives, while also planning to reduce or remove technical debt which is hidden but still present in the overall architecture.
A façade is placed between the API consumer and a back-end legacy API, and wraps (hides) the legacy implementation details of the back-end from the API consumer. Rather than hiding a legacy message format, as seen with the transformation façade, other legacy API implementation details are hidden from the consumer.
Where these legacy implementation details are cross-cutting concerns such as the security model in use, the API Management layer implements the wrapper.
For example, a legacy back-end API may have a dependency on a legacy security method such as TLS Mutual Authentication, and it is desirable to hide this from API consumers. The diagram below illustrates where API Management presents a OAuth2/OpenID Connect based security model to consumers and mediates this, acting as a client implementing TLS Mutual Authentication.
The characteristics of a legacy API may mean that the API Management Layer is not the best place to hide all the legacy behaviour of the back-end API. This is typically when some business logic or processing state is required to hide back-end behaviour. An additional middleware API layer would be required in this case, possibly in addition to the role of the API Management Layer to mediate security approaches.
You would use the wrapper façade typically where you have an existing legacy API which you want to expose quickly for consumption in a way which meets current standards.
However, you should prefer the simple pass-through API over the wrapper façade pattern as this adds additional complexity solely to hide technical debt from the API consumer. If there is no plan in place to address the technical debt present in the back-end service, this is an anti-pattern.
It is typically acceptable therefore to use this pattern to meet short term business objectives while also planning to reduce or remove technical debt which is hidden but still present in the overall architecture.