Tools for making HTTP requests and managing API interactions in modern web applications.
Description: Promise-based HTTP client for the browser and node.js with request/response interceptors and automatic JSON data transformation.
Key Features:
- Promise-based API
- Request/response interceptors
- Automatic JSON transformation
- Request/response transformation
- Error handling
- Request cancellation
- Wide browser support
Installation:
npm install axiosBasic Usage:
import axios from 'axios';
// Basic GET request
const fetchUsers = async () => {
try {
const response = await axios.get('https://jsonplaceholder.typicode.com/users');
return response.data;
} catch (error) {
console.error('Error fetching users:', error);
}
};
// POST request with data
const createUser = async (userData) => {
try {
const response = await axios.post('https://jsonplaceholder.typicode.com/users', userData);
return response.data;
} catch (error) {
console.error('Error creating user:', error);
}
};
// With interceptors
const api = axios.create({
baseURL: 'https://api.example.com',
timeout: 5000
});
// Request interceptor
api.interceptors.request.use(
(config) => {
const token = localStorage.getItem('token');
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
},
(error) => Promise.reject(error)
);
// Response interceptor
api.interceptors.response.use(
(response) => response,
(error) => {
if (error.response?.status === 401) {
// Handle unauthorized access
localStorage.removeItem('token');
window.location.href = '/login';
}
return Promise.reject(error);
}
);Use Cases: RESTful API calls, file uploads, request/response transformation
Description: Data fetching library with cache, revalidation, focus tracking, and more for React applications.
Key Features:
- Automatic caching
- Background revalidation
- Focus revalidation
- Error retry
- Pagination support
- TypeScript support
- Small bundle size
Installation:
npm install swrBasic Usage:
import useSWR from 'swr';
const fetcher = (url) => fetch(url).then((res) => res.json());
function Profile() {
const { data, error, isLoading } = useSWR('/api/user', fetcher);
if (error) return <div>Failed to load</div>;
if (isLoading) return <div>Loading...</div>;
return (
<div>
<h1>Hello {data.name}!</h1>
<p>Email: {data.email}</p>
</div>
);
}
// With conditional fetching
function User({ userId }) {
const { data, error } = useSWR(
userId ? `/api/users/${userId}` : null,
fetcher
);
if (error) return <div>Failed to load user</div>;
if (!data) return <div>Loading...</div>;
return <div>Hello {data.name}!</div>;
}
// With mutations
import useSWRMutation from 'swr/mutation';
async function updateUser(url, { arg }) {
return fetch(url, {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(arg),
}).then(res => res.json());
}
function UserForm({ userId }) {
const { trigger } = useSWRMutation(`/api/users/${userId}`, updateUser);
const handleSubmit = async (formData) => {
try {
await trigger(formData);
// Handle success
} catch (error) {
// Handle error
}
};
return (
<form onSubmit={handleSubmit}>
{/* Form fields */}
</form>
);
}Use Cases: Real-time data, caching, background updates, React applications
Description: Data fetching library with cache, revalidation, focus tracking, and more for React applications.
Key Features:
- Automatic caching
- Background revalidation
- Focus revalidation
- Error retry
- Pagination support
- TypeScript support
- Small bundle size
Installation:
npm install swrBasic Usage:
import useSWR from 'swr';
const fetcher = (url) => fetch(url).then((res) => res.json());
function Profile() {
const { data, error, isLoading } = useSWR('/api/user', fetcher);
if (error) return <div>Failed to load</div>;
if (isLoading) return <div>Loading...</div>;
return (
<div>
<h1>Hello {data.name}!</h1>
<p>Email: {data.email}</p>
</div>
);
}
// With conditional fetching
function User({ userId }) {
const { data, error } = useSWR(
userId ? `/api/users/${userId}` : null,
fetcher
);
if (error) return <div>Failed to load user</div>;
if (!data) return <div>Loading...</div>;
return <div>Hello {data.name}!</div>;
}
// With mutations
import useSWRMutation from 'swr/mutation';
async function updateUser(url, { arg }) {
return fetch(url, {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(arg),
}).then(res => res.json());
}
function UserForm({ userId }) {
const { trigger } = useSWRMutation(`/api/users/${userId}`, updateUser);
const handleSubmit = async (formData) => {
try {
await trigger(formData);
// Handle success
} catch (error) {
// Handle error
}
};
return (
<form onSubmit={handleSubmit}>
{/* Form fields */}
</form>
);
}Use Cases: Real-time data, caching, background updates, React applications
Description: Modern web API for making HTTP requests, built into modern browsers and Node.js.
Key Features:
- Native browser API
- Promise-based
- Stream support
- Request/Response objects
- No external dependencies
- Wide browser support
Basic Usage:
// Basic GET request
const fetchUsers = async () => {
try {
const response = await fetch('https://jsonplaceholder.typicode.com/users');
if (!response.ok) {
throw new Error('Network response was not ok');
}
const data = await response.json();
return data;
} catch (error) {
console.error('Error:', error);
}
};
// POST request with headers
const createUser = async (userData) => {
try {
const response = await fetch('https://jsonplaceholder.typicode.com/users', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(userData),
});
if (!response.ok) {
throw new Error('Failed to create user');
}
const data = await response.json();
return data;
} catch (error) {
console.error('Error:', error);
}
};
// With custom hook
import { useState, useEffect } from 'react';
function useFetch(url) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
const fetchData = async () => {
try {
setLoading(true);
const response = await fetch(url);
if (!response.ok) {
throw new Error('Network response was not ok');
}
const result = await response.json();
setData(result);
} catch (error) {
setError(error);
} finally {
setLoading(false);
}
};
fetchData();
}, [url]);
return { data, loading, error };
}
// Usage
function UsersList() {
const { data, loading, error } = useFetch('https://jsonplaceholder.typicode.com/users');
if (loading) return <div>Loading...</div>;
if (error) return <div>Error: {error.message}</div>;
return (
<ul>
{data?.map(user => (
<li key={user.id}>{user.name}</li>
))}
</ul>
);
}Use Cases: Simple HTTP requests, when you want to avoid external dependencies
| Library | Bundle Size | Caching | TypeScript | Learning Curve |
|---|---|---|---|---|
| Axios | Medium | Manual | Good | Low |
| SWR | Small | Automatic | Excellent | Low |
| Fetch API | None | Manual | Good | Low |
- Axios: When you need interceptors, automatic JSON transformation, or request/response transformation
- SWR: When you need automatic caching, background updates, and React integration
- Fetch API: When you want to avoid external dependencies and need simple HTTP requests
- Error Handling: Always implement proper error handling for network requests
- Loading States: Show loading indicators during API calls
- Caching: Implement appropriate caching strategies for your data
- Request Cancellation: Cancel requests when components unmount
- TypeScript: Use TypeScript for better type safety with API responses
- Retry Logic: Implement retry mechanisms for failed requests
- Rate Limiting: Respect API rate limits and implement backoff strategies
- Security: Validate and sanitize data from APIs
- Testing: Mock API calls in your tests
- Performance: Use request deduplication and proper caching
// Prevent duplicate requests for the same data
const requestCache = new Map();
const deduplicatedFetch = async (url) => {
if (requestCache.has(url)) {
return requestCache.get(url);
}
const promise = fetch(url).then(res => res.json());
requestCache.set(url, promise);
return promise;
};const fetchWithRetry = async (url, options = {}, retries = 3) => {
try {
const response = await fetch(url, options);
if (!response.ok) throw new Error(`HTTP ${response.status}`);
return response;
} catch (error) {
if (retries > 0) {
await new Promise(resolve => setTimeout(resolve, 1000 * (4 - retries)));
return fetchWithRetry(url, options, retries - 1);
}
throw error;
}
};