Advanced Usage
Custom Rate Limiting Per Resource
Section titled “Custom Rate Limiting Per Resource”Configure different rate limits for different resource types:
import ComicVine from 'comic-vine-sdk';import { InMemoryRateLimitStore } from '@http-client-toolkit/store-memory';
const client = new ComicVine({ apiKey: 'your-api-key', stores: { rateLimit: new InMemoryRateLimitStore({ defaultConfig: { limit: 200, windowMs: 3600000 }, // 200 req/hour default resourceConfigs: new Map([ ['issues', { limit: 100, windowMs: 3600000 }], // 100 req/hour ['characters', { limit: 300, windowMs: 3600000 }], // 300 req/hour ['volumes', { limit: 50, windowMs: 3600000 }], // 50 req/hour ]), }), },});Request Processing Flow
Section titled “Request Processing Flow”Every API request follows a 7-step priority sequence:
// Simplified internal flowasync function processRequest(url) { // 1. Cache Check - immediate return if cached const cached = await cache.get(requestHash); if (cached) return cached;
// 2. Deduplication - wait for in-progress identical request const inProgress = await dedupe.waitFor(requestHash); if (inProgress) return inProgress; await dedupe.register(requestHash);
// 3. Rate Limiting - check if request is allowed const canProceed = await rateLimit.canProceed(resource); if (!canProceed) { /* throw or wait */ }
// 4. Execute HTTP Request const response = await httpClient.get(url);
// 5. Record for Rate Limiting await rateLimit.record(resource);
// 6. Store in Cache await cache.set(requestHash, response);
// 7. Complete Deduplication await dedupe.complete(requestHash, response);
return response;}Deduplication in Practice
Section titled “Deduplication in Practice”Deduplication is especially useful when multiple parts of your application request the same data:
import { InMemoryCacheStore, InMemoryDedupeStore,} from '@http-client-toolkit/store-memory';
const client = new ComicVine({ apiKey: 'your-api-key', stores: { cache: new InMemoryCacheStore({ maxItems: 1000 }), dedupe: new InMemoryDedupeStore({ jobTimeoutMs: 300000 }), }, client: { defaultCacheTTL: 300, // 5 minutes },});
// Multiple components requesting the same character simultaneously// Only one HTTP request is madeconst [sidebar, header, detail] = await Promise.all([ client.character.retrieve(1443, { fieldList: ['id', 'name', 'image'] }), client.character.retrieve(1443, { fieldList: ['id', 'name', 'image'] }), client.character.retrieve(1443, { fieldList: ['id', 'name', 'image'] }),]);Collecting All Items with Auto Pagination
Section titled “Collecting All Items with Auto Pagination”Build a complete collection by iterating through all pages:
// Collect all issues in a volumeconst allIssues = [];
for await (const issue of client.issue.list({ fieldList: ['id', 'name', 'issueNumber', 'coverDate'], filter: { volume: 796 }, limit: 100,})) { allIssues.push(issue);}
console.log(`Collected ${allIssues.length} issues`);
// Sort by issue numberallIssues.sort((a, b) => (a.issueNumber ?? 0) - (b.issueNumber ?? 0));Adaptive Rate Limiting for Mixed Workloads
Section titled “Adaptive Rate Limiting for Mixed Workloads”Use priority-based rate limiting when your application has both interactive and background operations:
import { AdaptiveRateLimitStore } from '@http-client-toolkit/store-memory';
const client = new ComicVine({ apiKey: 'your-api-key', stores: { rateLimit: new AdaptiveRateLimitStore(), },});
// User-facing search gets priorityasync function searchCharacters(query: string) { return client.character.list({ filter: { name: query }, fieldList: ['id', 'name', 'image', 'publisher'], priority: 'user', limit: 20, });}
// Background sync gets remaining capacityasync function syncVolumes() { for await (const volume of client.volume.list({ priority: 'background', limit: 100, })) { await saveToDatabase(volume); }}Persistent Stores for Production
Section titled “Persistent Stores for Production”Use SQLite stores for data that survives restarts and works across processes:
import ComicVine from 'comic-vine-sdk';import { SQLiteCacheStore, SQLiteDedupeStore, SQLiteRateLimitStore,} from '@http-client-toolkit/store-sqlite';
const client = new ComicVine({ apiKey: 'your-api-key', stores: { cache: new SQLiteCacheStore({ database: './comic-vine.db' }), dedupe: new SQLiteDedupeStore({ database: './comic-vine.db' }), rateLimit: new SQLiteRateLimitStore({ database: './comic-vine.db' }), },});Browser Usage with CORS Proxy
Section titled “Browser Usage with CORS Proxy”The Comic Vine API doesn’t support CORS. Use a proxy server for browser requests:
const client = new ComicVine({ apiKey: 'your-api-key', baseUrl: 'https://your-proxy-server.com/api/',});
// Note: Never expose your API key in browser JavaScript// The proxy should handle API key injection server-side