
Research
/Security News
Mini Shai-Hulud Campaign Hits Red Hat Cloud Services npm Packages
A mini Shai-Hulud campaign compromised Red Hat Cloud Services npm packages to steal developer and CI/CD secrets during installation.
@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
The npm package @hazeljs/gateway receives a total of 177 weekly downloads. As such, @hazeljs/gateway popularity was classified as not popular.
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.

Research
/Security News
A mini Shai-Hulud campaign compromised Red Hat Cloud Services npm packages to steal developer and CI/CD secrets during installation.

Research
/Security News
The North Korean malware loader hides in a Packagist-listed package and its GitHub branch to fetch and execute remote code in a likely Contagious Interview-style lure.

Security News
The Rust project is moving toward formal rules on LLM use in contributions after months of internal debate over maintainer burden, code quality, and contributor experience.