← Back to principles

API

Validate at the Boundary

What this means in practice

Treat every integration boundary as untrusted and observable.

Validate all external inputs and downstream responses against explicit schemas, and fail in controlled ways when the data you depend on changes.

Capture enough structured information at the boundary to make triage straightforward, and build resilience into integrations through timeouts, retries, circuit breakers, and kill switches.

Why this matters

External systems change, fail, and behave unexpectedly. If integrations rely on assumptions, failures become silent, hard to diagnose, and costly to fix.

Boundary validation and consistent observability surface breaking changes early, reduce incident time, and protect the rest of the system from cascading failures.

Resilience patterns keep the product usable even when dependencies are degraded.

Practices that meet this principle

  • Validate downstream responses against schemas (for example: validate a response body matches an expected schema)

  • Validate external inputs at the boundary, and provide warnings for contract violations that matter

  • Log at integration boundaries (request, response, and errors) with sensible redaction and volume control

  • Use a standardised logging structure across all integrations to make searching and triage consistent

  • Extend type safety into query building and external data handling (for example: type-safe query builders such as Kysely or Drizzle)

  • Publish machine-readable interface documentation for async interactions (events, jobs, callbacks) where relevant (for example: AsyncAPI, OpenAPI callbacks, or an equivalent format)

  • Use kill switches for external integrations when appropriate (for example: outages, throttling, or degraded dependency performance). For example: wrap the integration call behind a runtime-configurable feature flag (LaunchDarkly, Unleash, or a database-backed config) so you can disable it without redeploying; or implement a circuit breaker that opens after a threshold of failures and routes to a safe fallback.

  • Apply resilience patterns: timeouts, retries with backoff, circuit breakers, and bulkheads

Validation

A project meets this principle when:

  • All integration boundaries validate the data they depend on, and detect breaking changes promptly

  • Boundary logs provide enough context to diagnose failures without requiring ad-hoc instrumentation

  • Logging is controllable (on and off, or sampled) and does not leak sensitive data

  • Integrations fail gracefully and can be disabled safely when dependencies are unhealthy

  • Resilience controls exist and are exercised (timeouts, retries, and circuit breakers)