Posted by Craig Hughes Sun, February 24, 2019 14:00:54
In the traditional two or three-tier world of web development, there is an inherent trust between the client and the server. Each is contextually aware of the other and withholds or shares information depending on the level of trust. The server may generate and persist session information about the client to enforce control or to simplify interaction. The client may do the same for a better user experience. In the world of APIs, this contextual awareness is not guaranteed since APIs can call or orchestrate other components where the context of the client may be different or unknown.
API architecture can be, and often is, layered. Since APIs offer abstraction via their interfaces, the consumer need not know, nor care about, what goes on behind the scenes of the interface. This also means that it should not matter to the consumer what the API does, as long as it sticks to its interface contract. This abstraction allows an API to do any orchestration, composition, translation or enrichment to the original request; be that calling other APIs, interfaces, databases, systems, etc. Basically, the consumer of the API may not know where their request is actually being fulfilled, or how many other components/interfaces are being consumed in the process.
On the counter side of this, components being orchestrated or composed are abstracted from the original request by the API consumer. They may not be contextually aware of the overall intentions of the original consumer, and ideally, need not be; they should only be concerned with responding to their specific request.
This potentially disparate awareness between the original API consumer and the components being manipulated by the API can be a problem for the traditional mindset. Some might struggle with this lack of awareness and see it as a potential risk in security, authorization, authentication or trust. This often becomes the excuse for not adhering to interface-based architecture principles and the insistence in sticking to a two or three-tiered architecture, even with APIs.
The trick here is to implement and understand a chain of trust. Each conversation in an end-to-end request should be based on an established trust between consumer and producer (or requester and responder). The client making the original request should have a trust relationship with the original API. The API, in turn, should have an established trust relationship with each of the components it orchestrates or consumes. And each of these components should have an established trust with their consumed components.
This trust and context can be established using a combination of patterns and approaches. These could include:
· Mutual TLS (or similar) to restrict boundaries to known systems,
· API Gateways to manage the consuming systems
· JWT to manage user authentication and authorization (using OAuth2, SAML, OIDC, etc.)
Picture from Pexels.com