api-service-layerlisted
Install: claude install-skill rabius-sunny/agent-skills
# HTTP Data-Fetching Architecture
A four-layer pattern for talking to a backend API: each layer has exactly one
job, so a change in one (auth scheme, caching strategy, response shape) never
leaks into the others.
```
axios instance → request wrapper → read hook (SWR) ↘
(transport) (typing) (caching reads) service object
(domain API surface)
```
## 1. Axios instance - transport and cross-cutting concerns
One `axios.create(...)` instance per app, configured once, imported everywhere
else. This is the only place that knows about the base URL, timeouts, and how
auth/errors are handled - so switching auth strategy or adding global retry
logic is a one-file change.
```ts
// services/api/client.ts
import axios from 'axios'
import Cookies from 'js-cookie'
const client = axios.create({
baseURL: process.env.NEXT_PUBLIC_API_ROOT,
timeout: 30000,
headers: { 'Content-Type': 'application/json' }
})
// Request interceptor: attach auth on every outgoing call
client.interceptors.request.use((config) => {
const token = Cookies.get('authToken')
if (token) config.headers.Authorization = `Bearer ${token}`
return config
})
// Response interceptor: centralize error side-effects (toast, logout-on-401, etc.)
client.interceptors.response.use(
(response) => response,
(error) => {
handleApiError(error)
return Promise.reject(error)
}
)
export default client
```
Nothing outside this file