@dbs-portal/core-api
Version:
HTTP client and API utilities for DBS Portal
257 lines • 7.83 kB
JavaScript
/**
* Advanced API client with interceptors, caching, retry logic, and more
* Now powered by Axios for robust HTTP handling
*/
import { HttpClient } from './http-client';
import { CacheManager } from '../cache/cache-manager';
import { RetryManager } from '../retry/retry-manager';
import { RateLimiter } from '../utils/rate-limiter';
/**
* Advanced API client with comprehensive features using Axios
*/
export class ApiClient {
httpClient;
cacheManager;
retryManager;
rateLimiter;
config;
interceptorIds = [];
constructor(config = {}) {
this.config = config;
this.httpClient = new HttpClient(config);
// Initialize optional features
if (config.cache?.enabled) {
this.cacheManager = new CacheManager(config.cache);
}
if (config.retry) {
this.retryManager = new RetryManager(config.retry);
}
if (config.rateLimit) {
this.rateLimiter = new RateLimiter(config.rateLimit);
}
// Set up Axios interceptors
this.setupAxiosInterceptors();
}
/**
* Set up Axios interceptors for caching, rate limiting, and event handling
*/
setupAxiosInterceptors() {
// Request interceptor for rate limiting and caching
const requestInterceptorId = this.httpClient.addRequestInterceptor(async (config) => {
// Apply rate limiting
if (this.rateLimiter) {
await this.rateLimiter.acquire();
}
// Call event handler
if (this.config.onRequest) {
this.config.onRequest(config);
}
return config;
}, (error) => {
return Promise.reject(error);
});
// Response interceptor for caching and event handling
const responseInterceptorId = this.httpClient.addResponseInterceptor(async (response) => {
const apiResponse = response;
// Call event handler
if (this.config.onResponse) {
this.config.onResponse(apiResponse);
}
// Cache the response if applicable
if (this.cacheManager &&
this.shouldCacheResponse(response.config, apiResponse)) {
await this.cacheManager.set(response.config, apiResponse);
}
return response;
}, (error) => {
// Call error event handler
if (this.config.onError) {
this.config.onError(error);
}
return Promise.reject(error);
});
this.interceptorIds.push(requestInterceptorId, responseInterceptorId);
}
/**
* Makes an HTTP request with all features applied
*/
async request(config) {
// Check cache first
if (this.cacheManager && this.shouldUseCache(config)) {
const cached = await this.cacheManager.get(config);
if (cached) {
return cached;
}
}
// Execute request with retry logic if configured
const executeRequest = async () => {
return await this.httpClient.request(config);
};
if (this.retryManager) {
return await this.retryManager.execute(executeRequest);
}
else {
return await executeRequest();
}
}
/**
* GET request
*/
async get(url, config) {
return this.request({ ...config, url, method: 'GET' });
}
/**
* POST request
*/
async post(url, data, config) {
return this.request({ ...config, url, method: 'POST', data });
}
/**
* PUT request
*/
async put(url, data, config) {
return this.request({ ...config, url, method: 'PUT', data });
}
/**
* PATCH request
*/
async patch(url, data, config) {
return this.request({ ...config, url, method: 'PATCH', data });
}
/**
* DELETE request
*/
async delete(url, config) {
return this.request({ ...config, url, method: 'DELETE' });
}
/**
* HEAD request
*/
async head(url, config) {
return this.request({ ...config, url, method: 'HEAD' });
}
/**
* OPTIONS request
*/
async options(url, config) {
return this.request({ ...config, url, method: 'OPTIONS' });
}
/**
* Adds a request interceptor using Axios
*/
addRequestInterceptor(onFulfilled, onRejected) {
return this.httpClient.addRequestInterceptor(onFulfilled, onRejected);
}
/**
* Adds a response interceptor using Axios
*/
addResponseInterceptor(onFulfilled, onRejected) {
return this.httpClient.addResponseInterceptor(onFulfilled, onRejected);
}
/**
* Removes a request interceptor
*/
removeRequestInterceptor(id) {
this.httpClient.removeRequestInterceptor(id);
}
/**
* Removes a response interceptor
*/
removeResponseInterceptor(id) {
this.httpClient.removeResponseInterceptor(id);
}
/**
* Clears all custom interceptors (keeps built-in ones)
*/
clearInterceptors() {
// Note: This only clears custom interceptors, not the built-in ones for caching/rate limiting
// The built-in interceptors are managed internally
}
/**
* Clears cache
*/
clearCache() {
if (this.cacheManager) {
this.cacheManager.clear();
}
}
/**
* Gets cache statistics
*/
getCacheStats() {
return this.cacheManager?.getStats() || null;
}
/**
* Updates client configuration
*/
updateConfig(config) {
this.config = { ...this.config, ...config };
// Clear existing interceptors
this.interceptorIds.forEach(id => {
this.httpClient.removeRequestInterceptor(id);
this.httpClient.removeResponseInterceptor(id);
});
this.interceptorIds = [];
// Update HTTP client
this.httpClient = new HttpClient(this.config);
// Re-setup interceptors with new config
this.setupAxiosInterceptors();
// Update cache manager
if (config.cache && this.cacheManager) {
this.cacheManager.updateConfig(config.cache);
}
// Update retry manager
if (config.retry && this.retryManager) {
this.retryManager.updateConfig(config.retry);
}
// Update rate limiter
if (config.rateLimit && this.rateLimiter) {
this.rateLimiter.updateConfig(config.rateLimit);
}
}
/**
* Gets current configuration
*/
getConfig() {
return { ...this.config };
}
/**
* Gets the underlying Axios instance for advanced usage
*/
getAxiosInstance() {
return this.httpClient.getAxiosInstance();
}
/**
* Gets the underlying HTTP client
*/
getHttpClient() {
return this.httpClient;
}
/**
* Determines if cache should be used for request
*/
shouldUseCache(config) {
if (!this.cacheManager)
return false;
// Only cache GET requests by default
if (config.method && config.method !== 'GET')
return false;
// Check custom cache condition
if (this.config.cache?.shouldCache) {
return this.config.cache.shouldCache(config);
}
return true;
}
/**
* Determines if response should be cached
*/
shouldCacheResponse(config, response) {
if (!this.cacheManager)
return false;
// Don't cache error responses
if (response.status >= 400)
return false;
return this.shouldUseCache(config);
}
}
//# sourceMappingURL=api-client.js.map