CLOUD CONCEPT

Adapter Pattern

The Adapter Pattern translates a provider-specific interface into a stable application interface so implementations can change without changing calling code.

Cloud Concepts Hub →

What is Adapter Pattern

An adapter isolates differences in request formats, authentication, responses, and errors behind a consistent contract. In generative AI architectures, adapters let applications use different foundation models while configuration controls which supported model or provider handles a request.

The Adapter Pattern is a structural design pattern that makes an existing interface usable through the interface an application expects. The application calls a stable contract, and an adapter translates that call into the operations required by a particular implementation. In cloud systems, adapters commonly sit between business logic and external APIs, storage systems, payment providers, or foundation model endpoints. The objective is to contain integration differences rather than spread provider-specific conditions throughout application code.

For foundation model integration, define an application-facing contract containing messages, generation settings, tool definitions, and an explicit response format. Each provider adapter maps supported fields into the provider's request schema and converts its response into a common result. That result might contain generated content, normalized completion status, usage information, and provider metadata. Streaming requires its own contract for incremental content, tool-call events, completion, and errors; a synchronous response wrapper does not automatically provide streaming compatibility.

A practical architecture exposes a stable endpoint through Amazon API Gateway and invokes adapter logic hosted in AWS Lambda. A routing component reads AWS AppConfig configuration that maps a logical model name, such as support-assistant, to an approved provider, model identifier, and adapter. The application continues calling the same endpoint while operators change the configuration. Configuration can also express approved fallback targets or rollout settings. Adapters perform interface translation; routing or strategy logic decides which adapter to invoke. These responsibilities are related but distinct.

Switching without code modifications is possible when the target provider and capabilities are already supported by deployed adapters. Adding an incompatible provider generally requires implementing and deploying another adapter, but the calling application can remain unchanged. Configuration updates also need validation, controlled rollout, and monitoring. Applications must retrieve refreshed configuration rather than load it permanently at startup, and operators should account for caching and deployment propagation time.

A common misconception is that a uniform API makes models interchangeable. Models differ in context limits, tokenization, tool support, structured output behavior, safety controls, and response quality. Validate required capabilities before routing and reject unsupported options rather than silently discarding them. Amazon Bedrock Converse provides a common interface across supported models, reducing translation work, but model-specific capabilities and parameters still require explicit handling.

Adapters introduce maintenance work and can hide useful provider features if the shared contract is too restrictive. Use a small stable core with explicit capability checks and carefully controlled extensions. Normalize errors while retaining diagnostic details, apply bounded retries only to suitable failures, and recognize that retries can incur additional inference charges. Automatic fallback must respect data residency, authorization, and approved-provider policies rather than send sensitive prompts to any available endpoint. Record the selected model, configuration version, latency, usage, and outcome without unnecessarily logging sensitive prompts. Contract tests and model evaluations should verify both interface compatibility and task quality before a routing change reaches production.

Key aspects of Adapter Pattern

Adapters isolate interface differences behind a stable contract, while configuration, capability checks, and routing policies enable controlled model switching.

Stable application contract

Define requests, responses, streaming events, and errors independently of a provider SDK. Business logic depends on this contract rather than on individual model APIs.

Provider-specific translation

Keep request mapping, authentication integration, response conversion, and error normalization inside each adapter. Preserve useful diagnostic metadata without forcing callers to understand provider-specific schemas.

Configuration-driven selection

Resolve logical model names to deployed adapters and model identifiers through validated runtime configuration. Switching among supported targets does not require changing application code, although a new provider integration may require a new adapter.

Explicit capability boundaries

Check context limits, tool support, modalities, and output requirements before invoking a model. A shared interface must not imply that every provider supports identical behavior.

Separation of translation and policy

Let routing policy choose the target while adapters handle interface differences. Enforce approved providers, regions, and data-handling rules on both primary and fallback routes.

Compatibility testing and observability

Use contract tests to verify adapter behavior and evaluations to measure model suitability. Track model identity, configuration version, errors, latency, and usage so configuration changes can be assessed and rolled back.

Cloud services for Adapter Pattern

API Gateway exposes a stable application endpoint, while Lambda runs routing and provider-specific adapters. AppConfig supplies validated mappings from logical model names to approved targets, allowing supported models to change without modifying callers. Adapters can invoke Bedrock through its common conversational APIs or translate requests for external providers, retrieving external credentials from Secrets Manager when needed. Configuration controls selection, but adapter code remains responsible for translation and capability enforcement. Together, these services support controlled switching when permissions, model access, compliance checks, configuration refresh, and compatibility tests are implemented explicitly.

AWS Lambda image AWS Lambda

Lambda can host provider adapters and routing logic behind a shared application interface. Keep provider SDK calls inside adapters, and evaluate execution duration, concurrency, payload, and streaming requirements before choosing the integration.

Open AWS Lambda →
AWS AppConfig image AWS AppConfig

AppConfig can distribute validated configuration that maps logical model names to approved adapters, providers, and model identifiers. Its deployment controls support gradual changes and alarm-driven rollback; application logic must retrieve and apply configuration updates.

Open AWS AppConfig →
Amazon API Gateway image Amazon API Gateway

API Gateway provides a stable API endpoint in front of adapter implementations and supports controls such as authorization and throttling. Simple mapping transformations can handle limited schema differences, but complex provider translation and model-selection policy generally belong in application logic.

Open Amazon API Gateway →
Amazon Bedrock

The Bedrock Converse and ConverseStream APIs provide common conversational interfaces across supported models, reducing adapter complexity. Adapters may still be needed to unify Bedrock with other providers or to handle model-specific options and capability differences.

Open Amazon Bedrock →
AWS Secrets Manager image AWS Secrets Manager

Secrets Manager can store credentials required by external model providers so adapters do not embed API keys in code or routing configuration. Grant each adapter access only to the secrets it requires and handle credential rotation appropriately.

Open AWS Secrets Manager →