Nano Fetch
A lightweight HTTP client library inspired by Axios, built with TypeScript.
Features
- Promise-based API
- Request and response interceptors
- Automatic JSON data transformation
- Request timeout support
- TypeScript support
- Configurable base URL
- Query parameter handling
- Custom headers support
- Endpoints registration
Installation
npm install nano-fetch
Usage
Basic Usage
import { create } from 'nano-fetch';
const api = create({
baseURL: 'https://api.example.com',
headers: {
'Authorization': 'Bearer token'
}
});
const response = await api.get('/users');
const newUser = await api.post('/users', {
name: 'John Doe',
email: 'john@example.com'
});
const updatedUser = await api.put('/users/1', {
name: 'John Smith'
});
await api.delete('/users/1');
Named Endpoints
You can register and call endpoints by name:
import { create } from 'nano-fetch';
const api = create({
baseURL: 'https://api.example.com'
});
api.registerEndpoint('getUser', {
method: 'GET',
path: '/users/:id',
config: {
params: { include: 'profile' }
}
});
api.registerEndpoints({
createUser: {
method: 'POST',
path: '/users',
config: {
headers: { 'Content-Type': 'application/json' }
}
},
updateUser: {
method: 'PUT',
path: '/users/:id'
}
});
const user = await api.call('getUser', null, { params: { id: 123 } });
const newUser = await api.call('createUser', {
name: 'John Doe',
email: 'john@example.com'
});
const updatedUser = await api.call('updateUser', {
name: 'John Smith'
}, { params: { id: 123 } });
Interceptors
You can add request and response interceptors to modify requests or responses:
api.interceptors.request.use(
(config) => {
config.headers['X-Custom-Header'] = 'value';
return config;
},
(error) => {
return Promise.reject(error);
}
);
api.interceptors.response.use(
(response) => {
response.data.customField = 'value';
return response;
},
(error) => {
return Promise.reject(error);
}
);
const requestInterceptorId = api.interceptors.request.use();
api.interceptors.request.eject(requestInterceptorId);
api.interceptors.request.clear();
api.interceptors.response.clear();
Configuration
You can configure the client with the following options:
const api = create({
baseURL: 'https://api.example.com',
headers: {
'Content-Type': 'application/json'
},
timeout: 5000,
params: {
api_key: 'your-api-key'
},
retry: {
count: 3,
delay: 1000,
shouldRetry: (error) => {
return error.message.includes('Network') ||
(error.response?.status >= 500 && error.response?.status < 600);
},
onRetry: (error, attempt) => {
console.log(`Retry attempt ${attempt} after error: ${error.message}`);
}
}
});
Retry Configuration
The retry configuration allows you to handle transient failures automatically:
const api = create({
retry: {
count: 3,
delay: 1000
}
});
const response = await api.get('/users', {
retry: {
count: 5,
delay: 2000,
shouldRetry: (error) => {
return error.message.includes('timeout');
},
onRetry: (error, attempt) => {
console.log(`Retrying request (attempt ${attempt})`);
}
}
});
api.registerEndpoint('getUser', {
method: 'GET',
path: '/users/:id',
config: {
retry: {
count: 2,
delay: 500
}
}
});
The retry configuration supports:
count
: Number of retry attempts (default: 0)
delay
: Delay between retries in milliseconds (default: 1000)
shouldRetry
: Function to determine if a request should be retried (default: retry on all errors)
onRetry
: Callback function called before each retry attempt
API Reference
Methods
get(url: string, config?: RequestConfig)
post(url: string, data?: any, config?: RequestConfig)
put(url: string, data?: any, config?: RequestConfig)
delete(url: string, config?: RequestConfig)
patch(url: string, data?: any, config?: RequestConfig)
executeCollection(collection: ApiCollection, options?: BatchRequestOptions)
Response Structure
interface Response<T> {
data: T;
status: number;
statusText: string;
headers: Record<string, string>;
config: RequestConfig;
}
License
MIT