Loading...
Loading...
Master enterprise API integration with proven patterns for authentication, error handling, rate limiting, and scalability. Real-world examples from integrating 100+ enterprise APIs.
Enterprise API integrations are complex: authentication schemes, rate limits, versioning, error handling, and reliability requirements. Poor integration architecture costs enterprises $500K+ in technical debt and failed projects.
This comprehensive guide shares 12 proven API integration patterns from our experience integrating 100+ enterprise APIs (Salesforce, SAP, Workday, ServiceNow, and more).
Common failure modes:
Problem: External APIs change frequently, breaking your code.
Solution: Create an adapter layer that translates between your domain model and the external API.
// Bad: Direct dependency on external API
class OrderService {
async createOrder(order: Order) {
const salesforceOrder = {
Name: order.customerName,
Amount__c: order.total,
// Tightly coupled to Salesforce structure
};
await salesforceAPI.create(salesforceOrder);
}
}
// Good: Adapter pattern
interface CRMAdapter {
createOrder(order: Order): Promise<string>;
}
class SalesforceAdapter implements CRMAdapter {
async createOrder(order: Order): Promise<string> {
const sfOrder = this.mapToCRM(order);
return await salesforceAPI.create(sfOrder);
}
private mapToCRM(order: Order) {
// Isolate mapping logic
}
}
class OrderService {
constructor(private crmAdapter: CRMAdapter) {}
async createOrder(order: Order) {
return await this.crmAdapter.createOrder(order);
}
}
Benefits:
Problem: When external API is down, your entire system crashes or times out.
Solution: Detect failures and stop making requests temporarily.
class CircuitBreaker {
private state: 'CLOSED' | 'OPEN' | 'HALF_OPEN' = 'CLOSED';
private failureCount = 0;
private lastFailureTime?: Date;
constructor(
private threshold = 5,
private timeout = 60000
) {}
async execute<T>(fn: () => Promise<T>): Promise<T> {
if (this.state === 'OPEN') {
if (Date.now() - this.lastFailureTime!.getTime() > this.timeout) {
this.state = 'HALF_OPEN';
} else {
throw new Error('Circuit breaker is OPEN');
}
}
try {
const result = await fn();
this.onSuccess();
return result;
} catch (error) {
this.onFailure();
throw error;
}
}
private onSuccess() {
this.failureCount = 0;
this.state = 'CLOSED';
}
private onFailure() {
this.failureCount++;
this.lastFailureTime = new Date();
if (this.failureCount >= this.threshold) {
this.state = 'OPEN';
}
}
}
Get professional API integration development →
Problem: All retries happen simultaneously, overwhelming the API.
Solution: Retry with exponentially increasing delays plus randomization.
async function retryWithBackoff<T>(
fn: () => Promise<T>,
maxRetries = 5
): Promise<T> {
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
return await fn();
} catch (error) {
if (attempt === maxRetries - 1) throw error;
const baseDelay = Math.pow(2, attempt) * 1000; // Exponential
const jitter = Math.random() * 1000; // Random jitter
const delay = baseDelay + jitter;
await sleep(delay);
}
}
throw new Error('Max retries exceeded');
}
Problem: Network failures cause duplicate API calls (double charging customers).
Solution: Use idempotency keys to make requests safely retryable.
class PaymentService {
async processPayment(
amount: number,
customerId: string
): Promise<Payment> {
// Generate idempotency key from request
const idempotencyKey = `${customerId}-${amount}-${Date.now()}`;
return await stripeAPI.charges.create(
{
amount,
currency: 'usd',
customer: customerId,
},
{
idempotencyKey, // Stripe deduplicates
}
);
}
}
Problem: API rate limits (429 errors) break integrations.
Solution: Implement token bucket algorithm with queue.
class RateLimiter {
private tokens: number;
private lastRefill: number;
private queue: Array<() => void> = [];
constructor(
private maxTokens: number,
private refillRate: number // tokens per second
) {
this.tokens = maxTokens;
this.lastRefill = Date.now();
}
async acquire(): Promise<void> {
this.refillTokens();
if (this.tokens > 0) {
this.tokens--;
return Promise.resolve();
}
// Wait for token
return new Promise((resolve) => {
this.queue.push(resolve);
});
}
private refillTokens() {
const now = Date.now();
const elapsed = (now - this.lastRefill) / 1000;
const tokensToAdd = elapsed * this.refillRate;
this.tokens = Math.min(
this.maxTokens,
this.tokens + tokensToAdd
);
this.lastRefill = now;
// Process queue
while (this.tokens > 0 && this.queue.length > 0) {
this.tokens--;
this.queue.shift()!();
}
}
}
Problem: Webhooks fail silently (network issues, server downtime).
Solution: Implement webhook queue with retries and dead letter queue.
interface WebhookEvent {
id: string;
type: string;
payload: any;
attemptCount: number;
}
class WebhookProcessor {
async processWebhook(event: WebhookEvent) {
try {
await this.handleEvent(event);
await this.markAsProcessed(event.id);
} catch (error) {
if (event.attemptCount < 5) {
await this.requeueWithDelay(event, event.attemptCount);
} else {
await this.moveToDeadLetterQueue(event, error);
await this.notifyOps(event, error);
}
}
}
private async requeueWithDelay(
event: WebhookEvent,
attempt: number
) {
const delay = Math.pow(2, attempt) * 60000; // Minutes
await queue.add(
{ ...event, attemptCount: attempt + 1 },
{ delay }
);
}
}
Explore our API development services →
Problem: Large datasets timeout or exhaust memory.
Solution: Implement cursor-based pagination.
async function fetchAllRecords<T>(
apiCall: (cursor?: string) => Promise<{
data: T[];
nextCursor?: string;
}>
): Promise<T[]> {
const allRecords: T[] = [];
let cursor: string | undefined;
do {
const response = await apiCall(cursor);
allRecords.push(...response.data);
cursor = response.nextCursor;
} while (cursor);
return allRecords;
}
Problem: One slow API call blocks all others (thread pool exhaustion).
Solution: Isolate different API calls with separate thread pools.
class BulkheadExecutor {
private pools = new Map<string, TaskQueue>();
async execute<T>(
pool: string,
fn: () => Promise<T>,
maxConcurrency = 10
): Promise<T> {
if (!this.pools.has(pool)) {
this.pools.set(pool, new TaskQueue(maxConcurrency));
}
return this.pools.get(pool)!.add(fn);
}
}
// Usage: Isolate Salesforce from Stripe calls
await bulkhead.execute('salesforce', () => sfAPI.query());
await bulkhead.execute('stripe', () => stripeAPI.charges());
Problem: Polling APIs wastes resources and has lag.
Solution: Use webhooks + event bus for real-time integration.
Architecture:
Benefits:
Essential metrics to track:
class APIClient {
async request<T>(endpoint: string): Promise<T> {
const start = Date.now();
try {
const result = await fetch(endpoint);
metrics.recordLatency(
endpoint,
Date.now() - start
);
metrics.incrementSuccess(endpoint);
return result;
} catch (error) {
metrics.incrementError(endpoint, error.status);
logger.error('API call failed', {
endpoint,
error,
duration: Date.now() - start,
});
throw error;
}
}
}
Company: E-commerce platform Challenge: Integrate Salesforce, Stripe, ShipStation, QuickBooks
Solution implemented:
Results:
✅ Adapter layer for external dependencies ✅ Circuit breaker for failure isolation ✅ Exponential backoff with jitter ✅ Idempotency keys for critical operations ✅ Rate limit management ✅ Webhook reliability (retries + DLQ) ✅ Proper pagination for large datasets ✅ Bulkhead isolation for resource protection ✅ Comprehensive logging and monitoring ✅ Documentation and runbooks
We've integrated 100+ enterprise APIs: ✅ Zero-downtime integrations ✅ 99.95% average reliability ✅ 50% faster development vs. in-house ✅ Comprehensive monitoring included
Schedule Free Integration Consultation →
About Daf-Devs: API integration specialists with 100+ successful enterprise integrations. Explore our services →
Our team can help you implement AI automation, cybersecurity, and web development solutions.
Subscribe to our newsletter and get weekly AI automation tips, case studies with real ROI numbers, and exclusive tutorials delivered straight to your inbox.
Join 1,000+ professionals. No spam, unsubscribe anytime.
A comprehensive technical comparison of React and Next.js for SaaS applications. Performance benchmarks, SEO capabilities, and real-world use cases analyzed.
Migrate to cloud without downtime, data loss, or budget overruns. Our proven 7-phase framework has helped 40+ enterprises achieve successful cloud migrations with 40% cost reduction.