Building strategic public and partner API experience: The power of experience adapter and an abstraction layer


As organisations look to take their offerings to the world outside for specific customers, partners or general public and grow their business, they must balance the risk of opening the door to internal mission-critical systems vs value provided. These offerings also must deliver the right experience, requiring an abstraction over the internal organisation services to aggregate, secure and optimise information passed outwards – this is where experience APIs come in!

Customers and Business partners use various channels, do you manage their experience?

Experience APIs are a layer of services that communicate with internal Domain services to build services of value for an external channel or partner. These APIs leverage policies to secure information, manage volumes with throttling/rate-limiting and talk to identity systems to handle authentication/authorization (coarse-grained). These APIs can also optimise the experience through good design such as response caching and can even be metered to measure utilization for specific cases

As Experience APIs come in a few flavours as they serve different needs, in this post we will explore some of the types of uses as well as key reasons for building this layer, their responsibilities, few common anti-patterns

What is an experience layer?

The experience layer consists of components which provide services to external channels or systems. These are your services sitting at the boundary and bridging the gap between the external and internal

Experience layer holds components which can be specific channel adapters (web adapter, mobile adapter etc) or partner adapters (b2b). We call the components in this layer “Experience Adapters” and provide specific implementation for a channel experience in these adapters

Figure 1: Experience layer and components for channels

Why?

While there are plenty of good reasons to build a layer of abstraction, I feel there are 3 key reasons here

  • Experience
  • Isolation
  • Security

Experience

Experience layers are built for delivering channel specific experiences. These backend components help the frontend components deliver more by managing the load on the “server” side vs “client” side

Experience layer components speak the specific language of the channel component, optimised in the protocol, data-format, information model, security etc to service the customers of that channel

Isolation

Experience layer components can isolate different client groups from each other (vertical silos) and isolate clients from internal systems (horizontal silos)

Providing a new experience adapter for a new client can add development & operational costs initially; however over time, isolation allows for

  • decoupling between cohorts & contexts
  • ability to change rapidly for specific client or channel demands
  • improved operability with ability to manage different throughput demands due to reduced run-time coupling

Security

Given this layer is at the boundary security is essential experience layers can implement context specific security which would be difficult to implement (too general) in internal services

While we want to ensure our internal domain services are secure and implement zero-trust between services, it is best to implement client-specific concerns at the edge. With this, here is what we implement in (across) our experience adapters for security

  1. Client verification via ClientID or API key: Applies to authenticated and unauthenticated contexts
  2. Service Throttling, SLA based request Rate-limiting
  3. User Authentication and Data Authorization for given user in an authenticated channel context
  4. implement good design principles to protect internal services from DoS attacks, especially with unauthenticated contexts

Types

There are 3 core types of experiences these components can offer

  1. Channel
  2. Partner
  3. Public

Channel

These are experience adapters for web, mobile or voice offerings you as an organisation provide to your direct customers in a self-serve fashion

Organisations often start with a “web” and a “mobile” experience layer, but soon realise that coupling iOS and Android teams to a single backend component can backfire!

When building channel specific adapters consider the following

  • Consuming teams: Is it a single team or different. Build one per team
  • Consuming context: A single portal team could be building micro-frontend or business context specific frontend. A single web experience layer for two different business contexts can be crippling later
  • Specification: You want to collaboratively build an API specification with the channel team. Consider yourself as an extension to the frontend team
  • Protocol & format: Giveup any dogma from internal APIs here. You serve the channel, go rpc if you have to and implement GraphQL based service on a local-copy of the internal data. Optimise for the customer experience!
  • Transactions: Ask early-on about the specific interactions – Command or Query? Can the command be eventually consistent with a 202 and Location or did you need a resource id now? How stale can the read be?

Partner

In constrast to a web or mobile channel, you could be building an API for a partner or partners. This is a B2B context and requires the following considerations

  • Isolation: When possible build a partner specific channel with agreed SLAs implemented in the experience adapter
  • Collaboration: Collaborate with partner engineers on the API specification to deliver a crip service faster
  • Security: Ensure your partners cannot access other services and access only this service. Use ClientID verification and 2-legged OAuth for system-system trust

Public

An Open API providing a standard service in a well published language is different to channel or partner use-cases above

Here an API is built without any specific consumer in mind with the goal of being “open”. Thus a the emphasis is on consistency, standards, security, isolation and documentation

Anti-patterns

Here are the top anti-patterns in Experience Layer design

  1. One-size fits all Experience service: Building a generic layer component for all use-cases
  2. Pass through Experience Service: only does translation and pushes traffic to core domain services. Provides little isolation and leaves systems open to DoS attacks
  3. Duplicating core Business Logic in Experience Service: watch-out for internal logic leaking to the boundaries. While we may want to validate and sanitise, there might be business logic specific to the core domain that we should avoid applying at the edge
  4. Protocol Dogma: “Our standard is REST only”
  5. Specification Dogma: Allow the frontend teams to write the specifications and collaborate! This leads to faster build cycles and better testing
  6. Zero Contract Tests: Not writing contract tests at all leads to poor specification and delays in experience layer integration
  7. Late Contract Tests: Not writing experience layer contract tests early in the design phase
  8. Observing and responding: Not writing synthetic functional tests

Conclusion

Channel, Partner, OpenAPI live at the boundary in the experience layer. This layer has components called experience adapters which are key in providing the following things

  1. Isolation
  2. Security
  3. Client specific feature

There are 3 core types of experiences these components can offer

  1. Channel
  2. Partner
  3. Public

Without an experience layer we expose our internal domain services to our clients and couple the outside with the inside. Without specific experience layer components or adapters we risk creating generic experience services coupling customers leading to poor experience, complex operational challenges, security loopholes and a vastly slower rate of change in adding new features

Leave a Comment

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s