
Security News
Frontier AI Is Now Critical Infrastructure
The Fable shutdown shows how quickly model access can become a business continuity risk for AI-dependent engineering teams.
@hazeljs/gateway
Advanced tools
Intelligent API Gateway for HazelJS - Version routing, canary deployments, circuit breaking, and traffic management
Intelligent API Gateway for HazelJS with version-based routing, canary deployments, circuit breaking, traffic management, and automatic rollback.
npm install @hazeljs/gateway
@hazeljs/config@hazeljs/resilienceThe config-driven approach reads all gateway settings from environment variables, making it easy to change behavior across environments without code changes.
gateway.config.ts)const gatewayConfig = () => ({
gateway: {
discovery: {
cacheEnabled: process.env.GATEWAY_CACHE_ENABLED !== 'false',
cacheTTL: parseInt(process.env.GATEWAY_CACHE_TTL || '30000'),
},
resilience: {
defaultCircuitBreaker: {
failureThreshold: parseInt(process.env.GATEWAY_CB_THRESHOLD || '5'),
resetTimeout: parseInt(process.env.GATEWAY_CB_RESET_TIMEOUT || '30000'),
},
defaultTimeout: parseInt(process.env.GATEWAY_DEFAULT_TIMEOUT || '5000'),
},
routes: [
{
path: '/api/users/**',
serviceName: 'user-service',
serviceConfig: { stripPrefix: '/api/users', addPrefix: '/users' },
circuitBreaker: {
failureThreshold: parseInt(process.env.USER_SVC_CB_THRESHOLD || '10'),
},
rateLimit: {
strategy: 'sliding-window',
max: parseInt(process.env.USER_SVC_RATE_LIMIT_MAX || '100'),
window: 60000,
},
},
{
path: '/api/orders/**',
serviceName: 'order-service',
canary: {
stable: { version: process.env.ORDER_STABLE_VERSION || 'v1', weight: 90 },
canary: { version: process.env.ORDER_CANARY_VERSION || 'v2', weight: 10 },
promotion: {
strategy: 'error-rate',
errorThreshold: parseInt(process.env.ORDER_CANARY_ERROR_THRESHOLD || '5'),
evaluationWindow: '5m',
autoPromote: true,
autoRollback: true,
steps: [10, 25, 50, 75, 100],
stepInterval: '10m',
},
},
},
],
},
});
export default gatewayConfig;
ConfigModule and GatewayServer.fromConfig()import { ConfigModule, ConfigService } from '@hazeljs/config';
import { GatewayServer, GatewayModule } from '@hazeljs/gateway';
import gatewayConfig from './gateway.config';
// Register the config loader
ConfigModule.forRoot({
envFilePath: ['.env', '.env.local'],
isGlobal: true,
load: [gatewayConfig],
});
// Register gateway module
GatewayModule.forRoot({ configKey: 'gateway' });
// Resolve and create
const configService = new ConfigService();
const config = GatewayModule.resolveConfig(configService);
const gateway = GatewayServer.fromConfig(config);
gateway.startCanaries();
# .env (development)
ORDER_CANARY_VERSION=v2
ORDER_CANARY_ERROR_THRESHOLD=5
USER_SVC_RATE_LIMIT_MAX=100
# .env.production
ORDER_CANARY_VERSION=v3
ORDER_CANARY_ERROR_THRESHOLD=2
USER_SVC_RATE_LIMIT_MAX=500
Decorators remain available for quick prototypes and when you prefer co-located configuration:
import {
Gateway,
Route,
ServiceRoute,
Canary,
GatewayCircuitBreaker,
GatewayRateLimit,
GatewayServer,
} from '@hazeljs/gateway';
@Gateway({
resilience: { defaultCircuitBreaker: { failureThreshold: 5 } },
metrics: { enabled: true, collectionInterval: '10s' },
})
class ApiGateway {
@Route('/api/users/**')
@ServiceRoute({ serviceName: 'user-service', stripPrefix: '/api/users', addPrefix: '/users' })
@GatewayCircuitBreaker({ failureThreshold: 10 })
@GatewayRateLimit({ strategy: 'sliding-window', max: 100, window: 60000 })
userService!: ServiceProxy;
@Route('/api/orders/**')
@ServiceRoute({ serviceName: 'order-service' })
@Canary({
stable: { version: 'v1', weight: 90 },
canary: { version: 'v2', weight: 10 },
promotion: {
strategy: 'error-rate',
errorThreshold: 5,
evaluationWindow: '5m',
autoPromote: true,
autoRollback: true,
steps: [10, 25, 50, 75, 100],
stepInterval: '10m',
},
})
orderService!: ServiceProxy;
}
const gateway = GatewayServer.fromClass(ApiGateway);
gateway.startCanaries();
When you deploy a new version, the gateway automatically:
Deploy v2 → 10% canary → [healthy?] → 25% → 50% → 75% → 100% ✓
↓
[errors > 5%] → Rollback to 0% ✗
gateway.on('canary:promote', (data) => {
console.log(`Step ${data.step}: canary at ${data.canaryWeight}%`);
});
gateway.on('canary:rollback', (data) => {
console.log(`Rolled back: ${data.canaryVersion} (trigger: ${data.trigger})`);
});
gateway.on('canary:complete', (data) => {
console.log(`${data.version} is now at 100%`);
});
| Strategy | How It Works | Example |
|---|---|---|
| Header | Client sends X-API-Version: v2 | Opt-in for specific clients |
| URI | Path prefix /v2/api/users | RESTful versioning |
| Query | ?version=v2 | Quick testing |
| Weighted | Percentage-based random | A/B testing, canary |
Use the gateway with HazelApp's built-in HTTP server:
import { HazelApp } from '@hazeljs/core';
import { GatewayServer, createGatewayHandler } from '@hazeljs/gateway';
const gateway = GatewayServer.fromConfig(config);
gateway.startCanaries();
const app = new HazelApp(AppModule);
app.addProxyHandler('/api', createGatewayHandler(gateway));
app.listen(3000);
addProxyHandler(pathPrefix, handler) runs after body parsing and before the router. Requests matching the path prefix are forwarded to the gateway.
const gateway = new GatewayServer({
discovery: { cacheEnabled: true },
metrics: { enabled: true },
});
gateway.addRoute({
path: '/api/users/**',
serviceName: 'user-service',
circuitBreaker: { failureThreshold: 5 },
});
const response = await gateway.handleRequest({
method: 'GET',
path: '/api/users/123',
headers: {},
});
| Prefix | Scope | Example |
|---|---|---|
GATEWAY_* | Global gateway settings | GATEWAY_DEFAULT_TIMEOUT=5000 |
GATEWAY_CB_* | Default circuit breaker | GATEWAY_CB_THRESHOLD=5 |
<SERVICE>_SVC_* | Per-service overrides | USER_SVC_RATE_LIMIT_MAX=100 |
<SERVICE>_CANARY_* | Canary deployment | ORDER_CANARY_ERROR_THRESHOLD=5 |
<SERVICE>_VERSION_* | Version routing | PAYMENT_DEFAULT_VERSION=v1 |
Apache 2.0
FAQs
Intelligent API Gateway for HazelJS - Version routing, canary deployments, circuit breaking, and traffic management
We found that @hazeljs/gateway demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
The Fable shutdown shows how quickly model access can become a business continuity risk for AI-dependent engineering teams.

Security News
AI agents are pulling packages into environments no scanner is watching, creating exposure before security teams can see it.

Security News
GitHub Actions checkout now blocks risky pull_request_target checkouts by default to help prevent pwn request supply chain attacks.