JAVASCRIPT

Creating a Generic API Client Wrapper for Reusability

Build a reusable and maintainable generic API client in JavaScript to centralize your fetch logic, handle common headers, and streamline all API interactions across your application.

class ApiClient {
    constructor(baseURL, defaultHeaders = {}) {
        this.baseURL = baseURL;
        this.defaultHeaders = {
            'Content-Type': 'application/json',
            ...defaultHeaders,
        };
    }

    async request(endpoint, options = {}) {
        const url = `${this.baseURL}${endpoint}`;
        const config = {
            ...options,
            headers: {
                ...this.defaultHeaders,
                ...options.headers,
            },
        };

        try {
            const response = await fetch(url, config);
            if (!response.ok) {
                const errorData = await response.json().catch(() => ({ message: response.statusText }));
                throw new Error(errorData.message || `API error: ${response.status}`);
            }
            // Handle 204 No Content gracefully
            if (response.status === 204) {
                return null;
            }
            return await response.json();
        } catch (error) {
            console.error('API request failed:', error);
            throw error;
        }
    }

    get(endpoint, params = {}, options = {}) {
        const queryString = new URLSearchParams(params).toString();
        const fullEndpoint = queryString ? `${endpoint}?${queryString}` : endpoint;
        return this.request(fullEndpoint, { ...options, method: 'GET' });
    }

    post(endpoint, data = {}, options = {}) {
        return this.request(endpoint, {
            ...options,
            method: 'POST',
            body: JSON.stringify(data),
        });
    }

    put(endpoint, data = {}, options = {}) {
        return this.request(endpoint, {
            ...options,
            method: 'PUT',
            body: JSON.stringify(data),
        });
    }

    delete(endpoint, options = {}) {
        return this.request(endpoint, { ...options, method: 'DELETE' });
    }

    // Method to set/update default headers (e.g., for auth token)
    setAuthToken(token) {
        this.defaultHeaders['Authorization'] = `Bearer ${token}`;
    }
}

// Example Usage:
// const myApiClient = new ApiClient('https://api.example.com/v1', {
//     'X-Custom-Header': 'MyValue'
// });

// myApiClient.setAuthToken('your_jwt_token_here');

// (async () => {
//     try {
//         const users = await myApiClient.get('/users', { limit: 5 });
//         console.log('Users:', users);

//         const newUser = await myApiClient.post('/users', { name: 'Alice', email: '[email protected]' });
//         console.log('New User:', newUser);
//     } catch (error) {
//         console.error('Operation failed:', error);
//     }
// })();
How it works: This JavaScript snippet provides a robust generic API client wrapper. It centralizes `fetch` logic, handles base URLs, default headers (like `Content-Type` and `Authorization`), and standardizes error handling. By providing helper methods for common HTTP verbs (GET, POST, PUT, DELETE), it promotes code reusability, maintainability, and consistency across all API interactions in your web application.

Need help integrating this into your project?

Our team of expert developers can help you build your custom application from scratch.

Hire DigitalCodeLabs