Full-Stack Project Development

Build a complete full-stack application from scratch including frontend, backend, database, authentication, and deployment.

advanced Backend Development 10 hours

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';
    }
}