dood-stream-client
Version:
๐ A feature-rich client for the DoodStream API with caching, logging, and error handling
165 lines (164 loc) โข 5.76 kB
JavaScript
import axios from "axios";
import { ErrorFactory } from "../errors/error-factory";
/**
* ๐ Base HTTP client for making API requests
*/
export class HttpClient {
/**
* Create a new HTTP client
*
* @param options - Client options
* @param logger - Logger instance
* @param cacheManager - Cache manager
*/
constructor(options, logger, cacheManager) {
this.apiKey = options.apiKey;
this.logger = logger;
this.cacheManager = cacheManager;
// Create axios instance
this.client = axios.create({
baseURL: options.baseUrl || "https://doodapi.com/api",
timeout: options.timeout || 30000,
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
});
// Add request interceptor for logging
this.client.interceptors.request.use((config) => {
this.logger.debug("๐ Request", {
method: config.method?.toUpperCase(),
url: config.url,
params: config.params,
});
return config;
});
// Add response interceptor for logging
this.client.interceptors.response.use((response) => {
this.logger.debug("โ
Response", {
status: response.status,
url: response.config.url,
data: response.data,
});
return response;
}, (error) => {
this.logger.error("โ Request failed", {
error: error.message,
config: error.config,
response: error.response?.data,
});
return Promise.reject(error);
});
}
/**
* ๐ Send a GET request
*
* @param endpoint - API endpoint
* @param params - Query parameters
* @param config - Axios request config
* @param enableCache - Whether to use caching for this request
* @returns Promise with response data
*/
async get(endpoint, params = {}, config = {}, enableCache = true) {
try {
// Add API key to parameters
const queryParams = { ...params, key: this.apiKey };
// Check cache if enabled
if (enableCache) {
const cacheKey = this.cacheManager.createKey(endpoint, queryParams);
const cachedData = this.cacheManager.get(cacheKey);
if (cachedData) {
return cachedData;
}
}
// Make the request
const response = await this.client.get(endpoint, {
...config,
params: queryParams,
});
// Handle unexpected response format
if (!response.data) {
throw ErrorFactory.createFromResponse(response, "Empty response received");
}
// Cache the response if enabled
if (enableCache) {
const cacheKey = this.cacheManager.createKey(endpoint, queryParams);
this.cacheManager.set(cacheKey, response.data);
}
return response.data;
}
catch (error) {
// Handle axios errors
if (error.isAxiosError) {
// Handle network errors
if (error.code === "ECONNABORTED") {
throw ErrorFactory.createTimeoutError(error);
}
if (!error.response) {
throw ErrorFactory.createNetworkError(error);
}
// Handle API errors with responses
throw ErrorFactory.createFromResponse(error.response);
}
// Rethrow any other errors
throw error;
}
}
/**
* ๐ค Send a POST request
*
* @param endpoint - API endpoint
* @param data - Request body data
* @param params - Query parameters
* @param config - Axios request config
* @returns Promise with response data
*/
async post(endpoint, data = {}, params = {}, config = {}) {
try {
// Add API key to parameters
const queryParams = { ...params, key: this.apiKey };
// Make the request
const response = await this.client.post(endpoint, data, {
...config,
params: queryParams,
});
// Handle unexpected response format
if (!response.data) {
throw ErrorFactory.createFromResponse(response, "Empty response received");
}
return response.data;
}
catch (error) {
// Handle axios errors
if (error.isAxiosError) {
// Handle network errors
if (error.code === "ECONNABORTED") {
throw ErrorFactory.createTimeoutError(error);
}
if (!error.response) {
throw ErrorFactory.createNetworkError(error);
}
// Handle API errors with responses
throw ErrorFactory.createFromResponse(error.response);
}
// Rethrow any other errors
throw error;
}
}
/**
* ๐งน Clear the cache for a specific endpoint
*
* @param endpoint - API endpoint
* @param params - Query parameters (excluding API key)
*/
clearCache(endpoint, params = {}) {
const cacheKey = this.cacheManager.createKey(endpoint, params);
this.cacheManager.delete(cacheKey);
}
/**
* ๐งน Clear the entire cache
*/
clearAllCache() {
this.cacheManager.clear();
}
}