Transform unreliable API calls into resilient, observable, and sophisticated multi-phase workflows with intelligent retry strategies, circuit breakers, and advanced execution patterns.
Modern applications need robust API orchestration with enterprise-grade reliability
Organize API calls into phases, branches, and decision trees with full control over execution order and state persistence.
Built-in circuit breakers, configurable retry strategies (exponential, linear, fixed), and sophisticated failure handling.
Sequential, concurrent, mixed, and non-linear execution patterns with configuration cascading to match your business logic perfectly.
Comprehensive hooks for monitoring, logging, error analysis, and execution history tracking in production.
Response caching with TTL, rate limiting, and concurrency control to maximize efficiency and respect API quotas.
Full TypeScript support with 50+ exported types ensuring compile-time safety and excellent IDE autocomplete.
npm install @emmvish/stable-request
Execute a single HTTP request with automatic retry on failure
import { stableRequest, RETRY_STRATEGIES } from '@emmvish/stable-request';
const userData = await stableRequest({
reqData: {
hostname: 'api.example.com',
path: '/users/123',
headers: { 'Authorization': 'Bearer token' }
},
resReq: true, // Return response data
attempts: 3, // Retry up to 3 times
wait: 1000, // 1 second between retries
retryStrategy: RETRY_STRATEGIES.EXPONENTIAL,
logAllErrors: true // Log all failed attempts
});
console.log(userData); // { id: 123, name: 'John' }
Execute multiple requests concurrently or sequentially
import { stableApiGateway } from '@emmvish/stable-request';
const requests = [
{
id: 'users',
requestOptions: { reqData: { hostname: 'api.example.com', path: '/users' }, resReq: true }
},
{
id: 'orders',
groupId: 'req-only',
requestOptions: { reqData: { hostname: 'api.example.com', path: '/orders/1/status' } }
},
{
id: 'products',
groupId: 'req-only',
requestOptions: { reqData: { hostname: 'api.example.com', path: '/products/3/status' } }
}
];
const results = await stableApiGateway(requests, {
requestGroups: [ // Apply common config by request group (overrides api-gateway commons)
{
id: 'req-only',
commonConfig: {
commonResReq: false
}
}
],
concurrentExecution: true, // Execute in parallel
commonRequestData: {
hostname: 'api.example.com',
headers: { 'X-API-Key': 'secret' }
},
commonAttempts: 2, // Retry each request twice
commonWait: 500
});
results.forEach(result => {
console.log(`${result.id}:`, result.data);
});
Orchestrate complex workflows with multiple phases
import { stableWorkflow, PHASE_DECISION_ACTIONS, REQUEST_METHODS } from '@emmvish/stable-request';
const phases = [
{
id: 'authentication',
requests: [
{ id: 'login', requestOptions: {
reqData: {
path: '/auth/login',
method: REQUEST_METHODS.POST,
body: { username: 'user', password: 'pass' }
},
resReq: true
}}
]
},
{
id: 'fetch-data',
concurrentExecution: true, // Execute in parallel
requests: [
{ id: 'profile', requestOptions: {
reqData: { path: '/profile' }, resReq: true
}},
{ id: 'orders', requestOptions: {
reqData: { path: '/orders' }, resReq: true
}},
{ id: 'settings', requestOptions: {
reqData: { path: '/settings' }, resReq: true
}}
]
}
];
const result = await stableWorkflow(phases, {
workflowId: 'user-data-sync',
commonRequestData: { hostname: 'api.example.com' },
commonAttempts: 3,
stopOnFirstPhaseError: true,
logPhaseResults: true
});
console.log(`Success: ${result.success}`);
Automatically retry failed requests with proper response analysis / error handling and sophisticated backoff strategies:
await stableRequest({
reqData: { hostname: 'api.example.com', path: '/data' },
attempts: 5,
wait: 1000,
retryStrategy: RETRY_STRATEGIES.EXPONENTIAL,
responseAnalyzer: async ({ data }) => {
return data.status === 'success'; // Retry if status is not 'success'
},
jitter: 500 // Add randomness
});
Prevent cascade failures and system overload:
await stableRequest({
reqData: { hostname: 'unreliable-api.com', path: '/data' },
attempts: 3,
circuitBreaker: {
failureThresholdPercentage: 50, // Open after 50% failures
successThresholdPercentage: 20, // Close after 20% successes
timeout: 60000 // Wait 60s before trying again
}
});
Cache responses to reduce load and improve performance:
await stableRequest({
reqData: { hostname: 'api.example.com', path: '/data' },
cache: {
enabled: true,
ttl: 300000 // Cache for 5 minutes
}
const sharedCachingManager = getGlobalCacheManager();
console.log('\n Caching Stats: ', sharedCachingManager.getStats())
sharedCachingManager.clear()
});
Control request rates and concurrent execution:
await stableApiGateway(requests, {
commonRequestData: { hostname: 'api.example.com', path: '/data' },
rateLimit: { maxRequests: 100, windowMs: 60000 }
});
Monitor and debug with powerful hooks:
await stableRequest({
reqData: { hostname: 'api.example.com', path: '/data' },
handleErrors: async ({ errorLog, executionContext }) => {
logger.error('Request failed', { errorLog, executionContext });
},
responseAnalyzer: async ({ data }) => {
return data.status === 'success';
}
});
Persist workflow state for recovery, distributed coordination, and long-running jobs:
await stableWorkflow(phases, {
workflowId: 'data-migration-123',
enableNonLinearExecution: true,
sharedBuffer: { completedPhases: [] },
commonStatePersistence: {
persistenceFunction: persistToRedis,
persistenceParams: { ttl: 3600, enableLocking: true },
loadBeforeHooks: true,
storeAfterHooks: true
}
});
Multi-source data fetching, enrichment, and batch uploading with validation
Order processing coordinating user validation, inventory, payment, and notifications
Production API health checks with SLA compliance tracking and alerting
Image processing, video encoding, or data transformation at scale
Feature flag testing with trial mode and probabilistic execution
Microservice coordination with proper dependencies and failure handling
Get started with stable-request today and transform your HTTP workflows