1.0.2 • Published 6 months ago
@_apparatus_/fetch-client v1.0.2
@apparatus/fetch-client
A thin wrapper for fetch with an axios inspired API. It boosts nice to have conveniences without compromising simplicity.
Installation
npm install @_apparatus_/fetch-clientFeatures
- 🔌 Fetch Clients - Reusable clients with predefined options like base URL and headers.
- 🔄 JSON Handling - Automatically serializes request body and sets
content-typeheader. - 📦 Response Parsing - One-step response handling based on content-type.
- ⚠️ Error Handling - Throws for non-2XX status codes by default, customizable through
statusoption. - ⏱️ Timeouts - Request timeout configuration with optional reset on retries.
- 🔁 Retries - Configurable retry attempts and delay for specific status codes.
- 🎯 Interceptors - Hooks to modify requests and responses.
Examples
Basic Usage
import { client } from '@_apparatus_/fetch-client'
// create a client instance
const api = client({
url: 'https://api.example.com',
headers: { authorization: `Basic ${token}` },
})
type User = { id: string; name: string; email: string }
// make requests
const { request, response, status, body: users } = await api.get<User[]>('/users')
console.log(users[0].name)
// post without stringify
const { body: user } = await api.post<User>('/users', undefined, {
name: 'John',
email: 'john@example.com',
})
console.log(user.id)Search parameters
const api = client({
url: 'https://api.example.com',
search: { version: '1.0', apiKey: 'xyz' },
})
// adds parameters: https://api.example.com/users?version=1.0&apiKey=xyz&orderBy=name
await api.get('/users', { search: { orderBy: 'name' } })Timeouts
const api = client({
url: 'https://api.example.com',
timeout: 5000, // timeout in milliseconds
timeoutReset: true, // reset timeout on retry
})
// override client options
await api.get('/users', { timeout: 10000 })Retries
// retry options set in the client
const api = client({
url: 'https://api.example.com',
retry: 5, // number of retries
retryDelay: [200, 400, 800], // delay in milliseconds for each retry
retryStatus: [408, 5], // retry only for 408 and 5XX status
})
// override client options
await api.get('/users', { retry: 2 })Status codes
const api = client({ url: 'https://api.example.com' })
const { status, body } = await api.get('/users/123', {
status: [2, 404], // will not throw for 2XX and 404 as valid codes
})
if (status === 404) console.log('User not found')
await api.get('/users', {
status: [200], // only accept exact 200 status
})Interceptors
const api = client({
url: 'https://api.example.com',
interceptRequest: request => request.headers.set('authorization', `Bearer ${getDynamicToken()}`),
})Error Handling
The library throws FetchError for network or status code errors:
try {
await api.get('/users')
} catch (error) {
if (error instanceof FetchError) {
console.log(error.status) // status code
console.log(error.body) // parsed error response
}
}API Reference
Fetch and call options
The client accepts most standard fetch options plus these additional options:
url: Base URL for all requestssearch: Additional URL search parametersheaders: Requests headersparse: Auto-parse response body (default: true)timeout: Request timeout in millisecondstimeoutReset: Reset timeout on retriesretry: Number of retry attemptsretryDelay: Array of delays between retriesretryStatus: Status codes that trigger retrystatus: Success status codes (1-digit values represent the entire status block)interceptRequest: Request interceptor functioninterceptResponse: Response interceptor function
See FetchOptions documentation in code for additional details and default values.
Response object
Each request returns a FetchResponse object containing:
request: Original Request objectresponse: Raw Response objectstatus: Response status codebody: Parsed response body