Files

2.1 KiB

Infrastructure Layer

App-wide technical adapters connecting the app to technical systems and shared runtime services: HTTP clients and interceptors, shared React Query helpers (keys, response types, error normalization), storage/browser adapters, formatting service adapters, technical config wrappers. No feature business logic.

infrastructure/
├── axios/
│   ├── index.ts              # configured axios client
│   ├── interceptors.ts       # request/response interceptors
│   └── axios.d.ts            # axios type augmentation
│
├── reactQuery/
│   ├── index.ts
│   ├── errors.ts             # query error handling helpers
│   ├── helpers.ts            # query key and pagination helpers
│   ├── queryParams.ts        # table/query-param mapping helpers
│   └── types.ts              # shared API response/query types
│
├── IntlDate.ts               # date formatting service adapter
└── IntlName.ts               # name formatting service adapter

Rules

  1. Feature-agnostic: no module business rules, no page/component composition, no entity mapping that belongs in a module data/mapper.
  2. API modules use infrastructure clients (import { axiosClient } from "#infrastructure/axios") instead of creating their own.
  3. React Query helpers shared across modules (key builders, list response types, pagination, error extraction) live here.
  4. UI never calls raw HTTP clients — view/page code uses data-layer hooks; direct #infrastructure/axios usage belongs in API/data modules.
  5. Generic formatting adapters (IntlDate, IntlName) may be consumed by UI.
  6. Keep app-state coupling narrow — prefer dependency injection; don't import feature modules into infrastructure.

Examples

import { axiosClient } from "#infrastructure/axios";

export class UserAPI {
  getDetailed(id: number) {
    return axiosClient.get(`/users/${id}`).then((response) => response.data);
  }
}
import {
  createKeyBuilder,
  getPaginationInfo,
} from "#infrastructure/reactQuery";

export const usersCacheKey = createKeyBuilder("USERS", "LIST");