ADR-0002: API layer abstraction with shared httpClient and domain modules
Status
Accepted
Date
2026-03-03
Context
The frontend talks to multiple backend domains (inventory,
suppliers, analytics) and needs consistent behavior for: - base
URL resolution - cookie-based sessions
(withCredentials) - 401 handling / auth boundaries
- resilient parsing and normalization of varied response
shapes
Forces/constraints: - Consistency: every API call must behave the same way for credentials, timeouts, and auth boundaries. - Maintainability: avoid re-implementing axios setup and interceptors per domain. - Testability: domain fetchers and hooks should be testable independently.
Decision
We centralize HTTP concerns in a shared client and organize API logic by domain:
- Shared HTTP client:
frontend/src/api/httpClient.ts- owns baseURL resolution,
withCredentials, timeout, and 401 redirect policy.
- Domain modules:
frontend/src/api/<domain>/*- optional structure per domain:
hooks/for React Query hooksutils/for normalization/shape tolerance
UI code consumes domain hooks/fetchers rather than importing Axios directly.
Alternatives Considered
- Direct
fetch()calls inside pages/components- Pros:
- No abstraction overhead
- Cons:
- Duplicates credentials, error handling, baseURL logic
- Harder to test consistently
- Pros:
- One giant “api.ts” file
- Pros:
- Single place to look
- Cons:
- Becomes unmaintainable as domains grow
- Encourages tangling unrelated endpoints
- Pros:
- Per-domain HTTP clients (one axios instance
per domain)
- Pros:
- Domain isolation
- Cons:
- Cross-cutting policies (401 redirect, cookies) drift over time
- Pros:
Consequences
Positive
- All consumers get consistent auth boundary behavior (401 redirect rules).
- Domain APIs remain cohesive and testable.
- Normalization utilities can be shared within a domain without polluting UI code.
Negative / Tradeoffs
- The shared
httpClientbecomes a critical dependency: changes must be careful. - Some domain exceptions (e.g., probe endpoints) must be encoded centrally.
Implementation Notes
- Where it is implemented (paths, key modules)
- Shared:
frontend/src/api/httpClient.ts - Domains:
frontend/src/api/inventory/*frontend/src/api/suppliers/*frontend/src/api/analytics/*
- Shared:
- Migration notes (if relevant)
- Avoid introducing new HTTP clients; extend domain modules instead.
- Testing implications (what should be tested and where)
- Unit tests for client policies and fetchers under
frontend/src/__tests__/unit/api/*.
- Unit tests for client policies and fetchers under
References
- Architecture docs: Data Access
- Diagrams:
- Related ADRs: ADR-0001, ADR-0006