← 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