Travel Supplier Adapter Pattern
Isolate hotel and flight provider contracts behind adapters with explicit DTO boundaries, normalization, error taxonomy and versioning.
The goal of a supplier adapter is to stop provider-specific contracts from leaking through the core domain. Each integration should live behind a controlled boundary.
Production scenario
A system integrates Expedia, Booking connectivity, a direct hotel API and a wholesaler. Each uses different authentication, DTOs, error codes and pricing semantics.
Recommended boundary
Core Search Service
-> ISupplierAdapter
-> Provider Request Mapper
-> HTTP/API Client
-> Provider Response Mapper
-> Error Translator
-> Capability MetadataAdapter contract
Typical responsibilities include Supports(context), Search(context), Reprice(offerRef), optional booking/cancel operations and Health().
Avoid one giant interface that forces every provider to pretend it supports the same capabilities.
Data model
Keep SearchContext, NormalizedOffer, SupplierReference, Money, CancellationPolicy and AvailabilityState in the core model.
Provider DTOs should remain inside the adapter boundary.
Trade-offs
An interface that is too generic hides important provider capabilities. An interface that is too provider-specific pollutes the core domain.
A useful compromise is a small shared contract plus capability metadata and optional capability interfaces.
Error handling
Do not collapse provider failures into generic 500 errors. Distinguish auth, rate limit, timeout, invalid request, no availability, upstream unavailable, retryable technical failure and non-retryable business failure.
Versioning
API-version migration should primarily affect the adapter implementation, not the entire search service. When possible, run old and new versions in shadow mode and compare normalized output.
Failure modes
Common mistakes include losing source IDs, erasing provider policy during normalization, retrying non-idempotent calls and putting ranking logic inside adapters.
Observability
Track latency, success, retries, normalized-offer count, mapping failures and raw-to-normalized validation errors for every adapter.
When not to use it
For a tiny one-provider prototype, a full adapter framework can be excessive. The value increases rapidly once a second provider is introduced.
Production checklist
Isolate DTOs, model capabilities, define error taxonomy, preserve source references, configure provider-specific timeout/retry, add contract tests, define version-migration plans and expose per-adapter metrics.
Planning a similar integration?
We can review requirements, feed/API design and the production approach with you.