← Back to principles

API

Abstract the architecture

What this means in practice

Your API behaves like a complete, self-contained system from a consumer’s perspective. Consumers never need to know what sits behind it, and nothing about internal implementation details should leak through responses, errors, naming, or behaviour. The contract is the boundary: it is stable, intentional, and expressed in consumer language.

Why this matters

When the architecture is properly abstracted, teams can change and evolve internals without breaking consumers. It reduces coupling, lowers integration friction, and makes APIs safer to adopt. It also improves security and operational resilience by preventing accidental disclosure of internal components and by ensuring failures are communicated in a way consumers can act on.

Practices that meet this principle

  • Define an explicit contract (request, response, error model) and treat it as the API boundary

  • Never surface raw downstream errors (for example: NJS, ORA, database, third-party errors)

  • Translate failures into consumer-friendly, actionable error responses

  • Do not expose internal service names, infrastructure identifiers, or third-party provider details in payloads, headers, or error messages

  • Ensure API interactions are traceable, explainable, and auditable (for example: correlation IDs, structured logging, clear ownership)

Validation

A project meets this principle when:

  • API responses and errors contain only consumer-relevant information

  • Internal architecture changes can be made without requiring consumer changes (unless the contract itself changes)

  • Errors are mapped to documented, stable error types with clear remediation guidance

  • Logging and tracing provide end-to-end observability without leaking internal implementation details to consumers