Chapter 7: API Integration
Chapter 7 of 15
Chapter 7: API Integration
7.1 Connecting Frontend to Backend
Proper API integration ensures reliable communication between frontend and backend.
// API service layer
// services/api.js
import axios from 'axios';
const api = axios.create({
baseURL: process.env.REACT_APP_API_URL,
headers: {
'Content-Type': 'application/json'
}
});
// Request interceptor - Add auth token
api.interceptors.request.use((config) => {
const token = localStorage.getItem('token');
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
});
// Response interceptor - Handle errors
api.interceptors.response.use(
(response) => response,
(error) => {
if (error.response?.status === 401) {
// Handle unauthorized
localStorage.removeItem('token');
window.location.href = '/login';
}
return Promise.reject(error);
}
);
export default api;
7.2 API Hooks
// Custom hook for API calls
function useApi(endpoint, options = {}) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
api.get(endpoint, options)
.then(response => {
setData(response.data);
setError(null);
})
.catch(err => setError(err))
.finally(() => setLoading(false));
}, [endpoint]);
return { data, loading, error };
}
// Usage
function UserProfile({ userId }) {
const { data: user, loading, error } = useApi(`/users/${userId}`);
if (loading) return <div>Loading...</div>;
if (error) return <div>Error: {error.message}</div>;
return <div>{user.name}</div>;
}
7.3 Error Handling
// Centralized error handling
function handleApiError(error) {
if (error.response) {
// Server responded with error
switch (error.response.status) {
case 400:
return 'Invalid request';
case 401:
return 'Unauthorized';
case 404:
return 'Resource not found';
case 500:
return 'Server error';
default:
return 'An error occurred';
}
} else if (error.request) {
return 'Network error';
} else {
return 'Request setup error';
}
}