第一部分:基础概念
第二部分:核心原理
第三部分:功能特性
第四部分:技术实现
第五部分:最佳实践
第六部分:实战应用
(接上一篇)
特点:
特点:
特点:
// 分层网关架构实现
class LayeredGatewayArchitecture {
constructor() {
this.layers = new Map();
this.initializeLayers();
}
initializeLayers() {
// 第一层:边缘网关层
this.layers.set('edge', {
name: '边缘网关层',
responsibilities: [
'SSL终止',
'DDoS防护',
'地理路由',
'静态内容缓存'
],
instances: []
});
// 第二层:业务网关层
this.layers.set('business', {
name: '业务网关层',
responsibilities: [
'认证授权',
'业务路由',
'API组合',
'协议转换'
],
instances: []
});
// 第三层:服务网关层
this.layers.set('service', {
name: '服务网关层',
responsibilities: [
'服务发现',
'负载均衡',
'熔断限流',
'监控日志'
],
instances: []
});
}
async routeRequest(request) {
let currentRequest = request;
// 按层次顺序处理请求
for (const [layerName, layer] of this.layers) {
console.log(`Processing request in ${layer.name}`);
currentRequest = await this.processLayer(layerName, currentRequest);
if (currentRequest.terminated) {
return currentRequest.response;
}
}
return currentRequest;
}
async processLayer(layerName, request) {
const layer = this.layers.get(layerName);
const processor = this.getLayerProcessor(layerName);
return await processor.process(request);
}
getLayerProcessor(layerName) {
switch (layerName) {
case 'edge':
return new EdgeGatewayProcessor();
case 'business':
return new BusinessGatewayProcessor();
case 'service':
return new ServiceGatewayProcessor();
default:
throw new Error(`Unknown layer: ${layerName}`);
}
}
}
// 边缘网关处理器
class EdgeGatewayProcessor {
async process(request) {
// SSL终止
await this.terminateSSL(request);
// DDoS防护
if (!await this.checkDDoSProtection(request)) {
return {
terminated: true,
response: this.createErrorResponse(429, 'Too Many Requests')
};
}
// 地理路由
const region = this.determineRegion(request);
request.region = region;
// 静态内容缓存检查
const cachedResponse = await this.checkStaticCache(request);
if (cachedResponse) {
return {
terminated: true,
response: cachedResponse
};
}
return request;
}
async terminateSSL(request) {
// SSL终止逻辑
request.secure = true;
request.originalProtocol = 'https';
}
async checkDDoSProtection(request) {
const clientIP = request.clientIP;
const requestCount = await this.getRequestCount(clientIP);
return requestCount < 1000; // 每分钟1000次请求限制
}
determineRegion(request) {
const clientIP = request.clientIP;
// 根据IP地址确定地理位置
return this.geoIPLookup(clientIP);
}
async checkStaticCache(request) {
if (this.isStaticResource(request.path)) {
return await this.getFromCDN(request.path);
}
return null;
}
isStaticResource(path) {
const staticExtensions = ['.js', '.css', '.png', '.jpg', '.gif', '.svg'];
return staticExtensions.some(ext => path.endsWith(ext));
}
}
// 业务网关处理器
class BusinessGatewayProcessor {
async process(request) {
// 认证授权
const authResult = await this.authenticate(request);
if (!authResult.success) {
return {
terminated: true,
response: this.createErrorResponse(401, 'Unauthorized')
};
}
request.user = authResult.user;
// 业务路由
const routeResult = await this.routeByBusiness(request);
request.targetService = routeResult.service;
request.targetVersion = routeResult.version;
// API组合
if (routeResult.requiresComposition) {
const composedResponse = await this.composeAPIs(request);
return {
terminated: true,
response: composedResponse
};
}
// 协议转换
if (routeResult.requiresProtocolConversion) {
request = await this.convertProtocol(request, routeResult.targetProtocol);
}
return request;
}
async authenticate(request) {
const token = request.headers.authorization;
if (!token) {
return { success: false };
}
// JWT验证逻辑
return await this.verifyJWT(token);
}
async routeByBusiness(request) {
const path = request.path;
const userType = request.user?.type;
// 根据业务规则进行路由
if (path.startsWith('/api/premium/') && userType !== 'premium') {
throw new Error('Premium access required');
}
return {
service: this.determineTargetService(path),
version: this.determineVersion(request),
requiresComposition: this.checkCompositionNeeded(path),
requiresProtocolConversion: this.checkProtocolConversion(request)
};
}
async composeAPIs(request) {
// API组合逻辑
const compositeData = {};
const requiredAPIs = this.getRequiredAPIs(request.path);
for (const api of requiredAPIs) {
const response = await this.callAPI(api, request);
compositeData[api.name] = response.data;
}
return {
status: 200,
data: compositeData
};
}
}
// 服务网关处理器
class ServiceGatewayProcessor {
async process(request) {
// 服务发现
const serviceInstances = await this.discoverService(request.targetService);
if (!serviceInstances || serviceInstances.length === 0) {
return {
terminated: true,
response: this.createErrorResponse(503, 'Service Unavailable')
};
}
// 负载均衡
const targetInstance = this.selectInstance(serviceInstances, request);
request.targetURL = `${targetInstance.address}:${targetInstance.port}`;
// 熔断检查
if (!await this.checkCircuitBreaker(targetInstance.id)) {
return {
terminated: true,
response: this.createErrorResponse(503, 'Circuit Breaker Open')
};
}
// 限流检查
const rateLimitResult = await this.checkRateLimit(request);
if (!rateLimitResult.allowed) {
return {
terminated: true,
response: this.createErrorResponse(429, 'Rate Limit Exceeded')
};
}
// 转发请求
const response = await this.forwardRequest(request);
// 记录监控日志
await this.recordMetrics(request, response);
return {
terminated: true,
response: response
};
}
async discoverService(serviceName) {
// 从服务注册中心获取服务实例
return await this.serviceRegistry.getInstances(serviceName);
}
selectInstance(instances, request) {
// 使用负载均衡算法选择实例
return this.loadBalancer.select(instances, request);
}
async checkCircuitBreaker(instanceId) {
return await this.circuitBreaker.canExecute(instanceId);
}
async forwardRequest(request) {
// 转发请求到目标服务
const response = await this.httpClient.request({
url: request.targetURL + request.path,
method: request.method,
headers: request.headers,
body: request.body
});
return response;
}
}
产品 | Kong | Zuul | Spring Cloud Gateway | Envoy | APISIX |
---|---|---|---|---|---|
开发语言 | Lua/Go | Java | Java | C++ | Lua |
性能 | 高 | 中 | 高 | 极高 | 高 |
扩展性 | 插件丰富 | 中等 | Spring生态 | 强大 | 插件丰富 |
学习曲线 | 中等 | 简单 | 中等 | 陡峭 | 中等 |
社区活跃度 | 很高 | 高 | 高 | 很高 | 高 |
云原生支持 | 好 | 一般 | 很好 | 极好 | 很好 |
AWS API Gateway vs Azure API Management vs Google Cloud Endpoints:
// API网关选型决策矩阵
class GatewaySelectionMatrix {
constructor() {
this.criteria = [
{ name: 'performance', weight: 0.25 },
{ name: 'scalability', weight: 0.20 },
{ name: 'features', weight: 0.20 },
{ name: 'cost', weight: 0.15 },
{ name: 'community', weight: 0.10 },
{ name: 'learning_curve', weight: 0.10 }
];
this.products = new Map();
this.initializeProducts();
}
initializeProducts() {
// Kong
this.products.set('kong', {
name: 'Kong',
scores: {
performance: 9,
scalability: 9,
features: 10,
cost: 7,
community: 9,
learning_curve: 7
},
pros: ['插件生态丰富', '性能优秀', '企业级特性'],
cons: ['学习成本较高', '企业版付费']
});
// Spring Cloud Gateway
this.products.set('spring-gateway', {
name: 'Spring Cloud Gateway',
scores: {
performance: 8,
scalability: 8,
features: 9,
cost: 10,
community: 8,
learning_curve: 8
},
pros: ['Spring生态集成', '配置简单', '免费开源'],
cons: ['绑定Spring生态', 'JVM内存消耗']
});
// Envoy
this.products.set('envoy', {
name: 'Envoy',
scores: {
performance: 10,
scalability: 10,
features: 8,
cost: 10,
community: 9,
learning_curve: 4
},
pros: ['性能极佳', '云原生设计', 'CNCF项目'],
cons: ['配置复杂', '学习曲线陡峭']
});
// APISIX
this.products.set('apisix', {
name: 'Apache APISIX',
scores: {
performance: 9,
scalability: 9,
features: 9,
cost: 10,
community: 8,
learning_curve: 7
},
pros: ['高性能', '插件丰富', '活跃开发'],
cons: ['相对较新', '文档待完善']
});
}
calculateScore(productName) {
const product = this.products.get(productName);
if (!product) {
throw new Error(`Product not found: ${productName}`);
}
let totalScore = 0;
for (const criterion of this.criteria) {
const score = product.scores[criterion.name] || 0;
totalScore += score * criterion.weight;
}
return {
product: product.name,
totalScore: totalScore.toFixed(2),
breakdown: product.scores,
pros: product.pros,
cons: product.cons
};
}
recommend(requirements = {}) {
const recommendations = [];
for (const [key, product] of this.products) {
const score = this.calculateScore(key);
// 根据特定需求调整分数
let adjustedScore = parseFloat(score.totalScore);
if (requirements.budget === 'low' && product.scores.cost < 8) {
adjustedScore -= 1;
}
if (requirements.team_size === 'small' && product.scores.learning_curve < 6) {
adjustedScore -= 1;
}
if (requirements.performance_critical && product.scores.performance < 8) {
adjustedScore -= 2;
}
recommendations.push({
...score,
adjustedScore: adjustedScore.toFixed(2)
});
}
return recommendations.sort((a, b) =>
parseFloat(b.adjustedScore) - parseFloat(a.adjustedScore)
);
}
generateReport(requirements) {
const recommendations = this.recommend(requirements);
let report = '# API网关选型建议报告\n\n';
report += '## 评估标准\n';
for (const criterion of this.criteria) {
report += `- ${criterion.name}: 权重 ${(criterion.weight * 100).toFixed(0)}%\n`;
}
report += '\n## 推荐排序\n\n';
recommendations.forEach((rec, index) => {
report += `### ${index + 1}. ${rec.product}\n`;
report += `- 综合得分: ${rec.adjustedScore}\n`;
report += `- 优势: ${rec.pros.join(', ')}\n`;
report += `- 劣势: ${rec.cons.join(', ')}\n\n`;
});
return report;
}
}
// 使用示例
const selector = new GatewaySelectionMatrix();
const requirements = {
budget: 'medium',
team_size: 'medium',
performance_critical: true,
cloud_native: true
};
const recommendations = selector.recommend(requirements);
console.log(selector.generateReport(requirements));
多级缓存架构:
// 多级缓存优化器
class MultiLevelCacheOptimizer {
constructor(config) {
this.l1Cache = new MemoryCache(config.l1);
this.l2Cache = new RedisCache(config.l2);
this.l3Cache = new DatabaseCache(config.l3);
this.cacheStrategy = config.strategy || 'write-through';
this.metrics = new CacheMetrics();
}
async get(key, options = {}) {
const startTime = Date.now();
let result = null;
let source = null;
try {
// L1缓存查询
result = await this.l1Cache.get(key);
if (result !== null) {
source = 'L1';
this.metrics.recordHit('L1');
return { data: result, source, latency: Date.now() - startTime };
}
this.metrics.recordMiss('L1');
// L2缓存查询
result = await this.l2Cache.get(key);
if (result !== null) {
source = 'L2';
this.metrics.recordHit('L2');
// 回写到L1缓存
await this.l1Cache.set(key, result, options.l1TTL);
return { data: result, source, latency: Date.now() - startTime };
}
this.metrics.recordMiss('L2');
// L3缓存查询
result = await this.l3Cache.get(key);
if (result !== null) {
source = 'L3';
this.metrics.recordHit('L3');
// 回写到L1和L2缓存
await Promise.all([
this.l1Cache.set(key, result, options.l1TTL),
this.l2Cache.set(key, result, options.l2TTL)
]);
return { data: result, source, latency: Date.now() - startTime };
}
this.metrics.recordMiss('L3');
return { data: null, source: 'MISS', latency: Date.now() - startTime };
} catch (error) {
this.metrics.recordError();
throw new CacheError(`Cache operation failed: ${error.message}`);
}
}
async set(key, value, options = {}) {
const operations = [];
switch (this.cacheStrategy) {
case 'write-through':
// 同时写入所有缓存层
operations.push(
this.l1Cache.set(key, value, options.l1TTL),
this.l2Cache.set(key, value, options.l2TTL),
this.l3Cache.set(key, value, options.l3TTL)
);
break;
case 'write-behind':
// 先写入L1,异步写入其他层
operations.push(this.l1Cache.set(key, value, options.l1TTL));
setImmediate(() => {
Promise.all([
this.l2Cache.set(key, value, options.l2TTL),
this.l3Cache.set(key, value, options.l3TTL)
]).catch(error => {
console.error('Write-behind cache operation failed:', error);
});
});
break;
case 'write-around':
// 只写入L2和L3,跳过L1
operations.push(
this.l2Cache.set(key, value, options.l2TTL),
this.l3Cache.set(key, value, options.l3TTL)
);
break;
}
await Promise.all(operations);
}
async invalidate(pattern) {
// 并行清理所有缓存层
await Promise.all([
this.l1Cache.invalidate(pattern),
this.l2Cache.invalidate(pattern),
this.l3Cache.invalidate(pattern)
]);
}
// 智能预热
async warmup(keys, dataLoader) {
const warmupPromises = keys.map(async (key) => {
try {
const data = await dataLoader(key);
if (data !== null) {
await this.set(key, data, {
l1TTL: 3600, // 1小时
l2TTL: 7200, // 2小时
l3TTL: 86400 // 24小时
});
}
} catch (error) {
console.error(`Warmup failed for key ${key}:`, error);
}
});
await Promise.all(warmupPromises);
}
// 缓存统计
getStats() {
return {
l1: this.metrics.getStats('L1'),
l2: this.metrics.getStats('L2'),
l3: this.metrics.getStats('L3'),
overall: this.metrics.getOverallStats()
};
}
}
// 内存缓存实现
class MemoryCache {
constructor(config = {}) {
this.maxSize = config.maxSize || 1000;
this.ttl = config.ttl || 300;
this.cache = new Map();
this.accessTimes = new Map();
this.startCleanupTimer();
}
async get(key) {
const item = this.cache.get(key);
if (!item) return null;
// 检查是否过期
if (Date.now() > item.expireAt) {
this.cache.delete(key);
this.accessTimes.delete(key);
return null;
}
// 更新访问时间(LRU)
this.accessTimes.set(key, Date.now());
return item.value;
}
async set(key, value, ttl = this.ttl) {
// 检查容量限制
if (this.cache.size >= this.maxSize && !this.cache.has(key)) {
this.evictLRU();
}
const expireAt = Date.now() + (ttl * 1000);
this.cache.set(key, { value, expireAt });
this.accessTimes.set(key, Date.now());
}
evictLRU() {
let oldestKey = null;
let oldestTime = Date.now();
for (const [key, time] of this.accessTimes) {
if (time < oldestTime) {
oldestTime = time;
oldestKey = key;
}
}
if (oldestKey) {
this.cache.delete(oldestKey);
this.accessTimes.delete(oldestKey);
}
}
async invalidate(pattern) {
const regex = new RegExp(pattern.replace(/\*/g, '.*'));
const keysToDelete = [];
for (const key of this.cache.keys()) {
if (regex.test(key)) {
keysToDelete.push(key);
}
}
for (const key of keysToDelete) {
this.cache.delete(key);
this.accessTimes.delete(key);
}
}
startCleanupTimer() {
setInterval(() => {
const now = Date.now();
const expiredKeys = [];
for (const [key, item] of this.cache) {
if (now > item.expireAt) {
expiredKeys.push(key);
}
}
for (const key of expiredKeys) {
this.cache.delete(key);
this.accessTimes.delete(key);
}
}, 60000); // 每分钟清理一次
}
}
// 缓存指标收集器
class CacheMetrics {
constructor() {
this.stats = {
L1: { hits: 0, misses: 0, errors: 0 },
L2: { hits: 0, misses: 0, errors: 0 },
L3: { hits: 0, misses: 0, errors: 0 }
};
}
recordHit(level) {
this.stats[level].hits++;
}
recordMiss(level) {
this.stats[level].misses++;
}
recordError() {
// 记录错误到所有级别
Object.values(this.stats).forEach(stat => stat.errors++);
}
getStats(level) {
const stat = this.stats[level];
const total = stat.hits + stat.misses;
const hitRate = total > 0 ? (stat.hits / total * 100).toFixed(2) : 0;
return {
hits: stat.hits,
misses: stat.misses,
errors: stat.errors,
hitRate: `${hitRate}%`,
total: total
};
}
getOverallStats() {
let totalHits = 0;
let totalMisses = 0;
let totalErrors = 0;
Object.values(this.stats).forEach(stat => {
totalHits += stat.hits;
totalMisses += stat.misses;
totalErrors += stat.errors;
});
const total = totalHits + totalMisses;
const overallHitRate = total > 0 ? (totalHits / total * 100).toFixed(2) : 0;
return {
hits: totalHits,
misses: totalMisses,
errors: totalErrors,
hitRate: `${overallHitRate}%`,
total: total
};
}
}
智能连接池管理:
// 智能连接池管理器
class IntelligentConnectionPool {
constructor(config) {
this.config = {
minConnections: config.minConnections || 5,
maxConnections: config.maxConnections || 50,
acquireTimeout: config.acquireTimeout || 30000,
idleTimeout: config.idleTimeout || 300000,
healthCheckInterval: config.healthCheckInterval || 60000,
...config
};
this.pool = [];
this.activeConnections = new Set();
this.waitingQueue = [];
this.metrics = new ConnectionPoolMetrics();
this.initializePool();
this.startHealthCheck();
this.startMetricsCollection();
}
async initializePool() {
// 创建最小数量的连接
const initialConnections = [];
for (let i = 0; i < this.config.minConnections; i++) {
initialConnections.push(this.createConnection());
}
const connections = await Promise.all(initialConnections);
this.pool.push(...connections);
}
async acquire() {
return new Promise((resolve, reject) => {
const timeout = setTimeout(() => {
reject(new Error('Connection acquire timeout'));
}, this.config.acquireTimeout);
this.waitingQueue.push({ resolve, reject, timeout });
this.processQueue();
});
}
async processQueue() {
while (this.waitingQueue.length > 0) {
// 检查是否有可用连接
const availableConnection = this.getAvailableConnection();
if (availableConnection) {
const waiter = this.waitingQueue.shift();
clearTimeout(waiter.timeout);
this.activeConnections.add(availableConnection);
this.metrics.recordAcquire();
waiter.resolve(availableConnection);
} else if (this.canCreateNewConnection()) {
// 创建新连接
try {
const newConnection = await this.createConnection();
const waiter = this.waitingQueue.shift();
clearTimeout(waiter.timeout);
this.activeConnections.add(newConnection);
this.metrics.recordAcquire();
waiter.resolve(newConnection);
} catch (error) {
const waiter = this.waitingQueue.shift();
clearTimeout(waiter.timeout);
waiter.reject(error);
}
} else {
// 无法获取连接,等待释放
break;
}
}
}
getAvailableConnection() {
// 优先选择最近使用的健康连接
const healthyConnections = this.pool.filter(conn =>
conn.isHealthy && !this.activeConnections.has(conn)
);
if (healthyConnections.length === 0) return null;
// 按最后使用时间排序,选择最近使用的
healthyConnections.sort((a, b) => b.lastUsed - a.lastUsed);
return healthyConnections[0];
}
canCreateNewConnection() {
const totalConnections = this.pool.length + this.activeConnections.size;
return totalConnections < this.config.maxConnections;
}
async createConnection() {
const connection = {
id: this.generateConnectionId(),
socket: await this.establishSocket(),
isHealthy: true,
createdAt: Date.now(),
lastUsed: Date.now(),
useCount: 0
};
this.pool.push(connection);
this.metrics.recordConnectionCreated();
return connection;
}
async establishSocket() {
// 建立实际的网络连接
const net = require('net');
return new Promise((resolve, reject) => {
const socket = new net.Socket();
socket.connect(this.config.port, this.config.host, () => {
socket.setKeepAlive(true);
socket.setNoDelay(true);
resolve(socket);
});
socket.on('error', reject);
socket.setTimeout(this.config.connectTimeout || 10000, () => {
reject(new Error('Connection timeout'));
});
});
}
release(connection) {
if (!this.activeConnections.has(connection)) {
return; // 连接未被激活
}
this.activeConnections.delete(connection);
connection.lastUsed = Date.now();
connection.useCount++;
this.metrics.recordRelease();
// 检查连接是否应该被销毁
if (this.shouldDestroyConnection(connection)) {
this.destroyConnection(connection);
} else {
// 处理等待队列
this.processQueue();
}
}
shouldDestroyConnection(connection) {
const now = Date.now();
// 检查空闲时间
if (now - connection.lastUsed > this.config.idleTimeout) {
return true;
}
// 检查连接健康状态
if (!connection.isHealthy) {
return true;
}
// 检查是否超过最大使用次数
if (this.config.maxUseCount && connection.useCount > this.config.maxUseCount) {
return true;
}
// 检查是否超过连接最大生存时间
if (this.config.maxLifetime && now - connection.createdAt > this.config.maxLifetime) {
return true;
}
return false;
}
destroyConnection(connection) {
// 从池中移除
const index = this.pool.indexOf(connection);
if (index !== -1) {
this.pool.splice(index, 1);
}
// 关闭socket连接
if (connection.socket) {
connection.socket.destroy();
}
this.metrics.recordConnectionDestroyed();
}
startHealthCheck() {
setInterval(async () => {
await this.performHealthCheck();
}, this.config.healthCheckInterval);
}
async performHealthCheck() {
const healthCheckPromises = this.pool.map(async (connection) => {
try {
const isHealthy = await this.checkConnectionHealth(connection);
connection.isHealthy = isHealthy;
if (!isHealthy && !this.activeConnections.has(connection)) {
this.destroyConnection(connection);
}
} catch (error) {
connection.isHealthy = false;
console.error(`Health check failed for connection ${connection.id}:`, error);
}
});
await Promise.all(healthCheckPromises);
// 确保最小连接数
await this.ensureMinimumConnections();
}
async checkConnectionHealth(connection) {
if (!connection.socket || connection.socket.destroyed) {
return false;
}
// 发送ping消息检查连接
return new Promise((resolve) => {
const timeout = setTimeout(() => resolve(false), 5000);
connection.socket.write('PING\n');
const onData = (data) => {
if (data.toString().includes('PONG')) {
clearTimeout(timeout);
connection.socket.removeListener('data', onData);
resolve(true);
}
};
connection.socket.on('data', onData);
});
}
async ensureMinimumConnections() {
const healthyConnections = this.pool.filter(conn => conn.isHealthy).length;
const connectionsNeeded = this.config.minConnections - healthyConnections;
if (connectionsNeeded > 0) {
const newConnections = [];
for (let i = 0; i < connectionsNeeded; i++) {
newConnections.push(this.createConnection());
}
try {
await Promise.all(newConnections);
} catch (error) {
console.error('Failed to create minimum connections:', error);
}
}
}
generateConnectionId() {
return `conn_${Date.now()}_${Math.random().toString(36).substring(2)}`;
}
getStats() {
return {
totalConnections: this.pool.length,
activeConnections: this.activeConnections.size,
idleConnections: this.pool.length - this.activeConnections.size,
waitingRequests: this.waitingQueue.length,
healthyConnections: this.pool.filter(conn => conn.isHealthy).length,
metrics: this.metrics.getStats()
};
}
}
// 连接池指标收集器
class ConnectionPoolMetrics {
constructor() {
this.metrics = {
connectionsCreated: 0,
connectionsDestroyed: 0,
acquireCount: 0,
releaseCount: 0,
acquireTime: [],
errors: 0
};
}
recordConnectionCreated() {
this.metrics.connectionsCreated++;
}
recordConnectionDestroyed() {
this.metrics.connectionsDestroyed++;
}
recordAcquire() {
this.metrics.acquireCount++;
}
recordRelease() {
this.metrics.releaseCount++;
}
recordAcquireTime(time) {
this.metrics.acquireTime.push(time);
if (this.metrics.acquireTime.length > 1000) {
this.metrics.acquireTime.shift();
}
}
recordError() {
this.metrics.errors++;
}
getStats() {
const avgAcquireTime = this.metrics.acquireTime.length > 0
? this.metrics.acquireTime.reduce((a, b) => a + b, 0) / this.metrics.acquireTime.length
: 0;
return {
...this.metrics,
averageAcquireTime: avgAcquireTime.toFixed(2) + 'ms',
activeConnectionsLifetime: this.metrics.acquireCount - this.metrics.releaseCount
};
}
}
批处理与流水线:
// 批处理优化器
class BatchProcessor {
constructor(config) {
this.config = {
batchSize: config.batchSize || 100,
flushInterval: config.flushInterval || 1000,
maxWaitTime: config.maxWaitTime || 5000,
concurrency: config.concurrency || 5,
...config
};
this.batches = new Map();
this.timers = new Map();
this.processor = config.processor;
this.metrics = new BatchMetrics();
}
async add(key, item) {
if (!this.batches.has(key)) {
this.batches.set(key, []);
this.startTimer(key);
}
const batch = this.batches.get(key);
batch.push({
item: item,
timestamp: Date.now(),
resolve: null,
reject: null
});
// 如果批次满了,立即处理
if (batch.length >= this.config.batchSize) {
this.flush(key);
}
// 返回Promise以支持异步等待
return new Promise((resolve, reject) => {
batch[batch.length - 1].resolve = resolve;
batch[batch.length - 1].reject = reject;
});
}
startTimer(key) {
const timer = setTimeout(() => {
this.flush(key);
}, this.config.flushInterval);
this.timers.set(key, timer);
}
async flush(key) {
const batch = this.batches.get(key);
if (!batch || batch.length === 0) return;
// 清理定时器
const timer = this.timers.get(key);
if (timer) {
clearTimeout(timer);
this.timers.delete(key);
}
// 移除批次
this.batches.delete(key);
try {
// 检查是否有项目等待太久
const now = Date.now();
const expiredItems = batch.filter(
item => now - item.timestamp > this.config.maxWaitTime
);
if (expiredItems.length > 0) {
console.warn(`${expiredItems.length} items exceeded max wait time`);
}
// 处理批次
const items = batch.map(b => b.item);
const startTime = Date.now();
const results = await this.processor(key, items);
const processingTime = Date.now() - startTime;
this.metrics.recordBatch(items.length, processingTime);
// 回调处理结果
batch.forEach((batchItem, index) => {
if (batchItem.resolve) {
batchItem.resolve(results[index]);
}
});
} catch (error) {
this.metrics.recordError();
// 回调错误
batch.forEach(batchItem => {
if (batchItem.reject) {
batchItem.reject(error);
}
});
}
}
// 强制刷新所有批次
async flushAll() {
const flushPromises = [];
for (const key of this.batches.keys()) {
flushPromises.push(this.flush(key));
}
await Promise.all(flushPromises);
}
getStats() {
return {
activeBatches: this.batches.size,
pendingItems: Array.from(this.batches.values())
.reduce((total, batch) => total + batch.length, 0),
metrics: this.metrics.getStats()
};
}
}
// 流水线处理器
class PipelineProcessor {
constructor() {
this.stages = [];
this.metrics = new PipelineMetrics();
}
addStage(name, processor, config = {}) {
this.stages.push({
name: name,
processor: processor,
parallel: config.parallel || false,
concurrency: config.concurrency || 1,
timeout: config.timeout || 30000
});
}
async process(input, context = {}) {
let data = input;
const pipeline = {
id: this.generatePipelineId(),
startTime: Date.now(),
stages: []
};
try {
for (const stage of this.stages) {
const stageStartTime = Date.now();
try {
if (stage.parallel) {
data = await this.processParallelStage(stage, data, context);
} else {
data = await this.processSequentialStage(stage, data, context);
}
const stageTime = Date.now() - stageStartTime;
pipeline.stages.push({
name: stage.name,
duration: stageTime,
success: true
});
this.metrics.recordStageSuccess(stage.name, stageTime);
} catch (error) {
const stageTime = Date.now() - stageStartTime;
pipeline.stages.push({
name: stage.name,
duration: stageTime,
success: false,
error: error.message
});
this.metrics.recordStageError(stage.name, stageTime);
throw error;
}
}
const totalTime = Date.now() - pipeline.startTime;
this.metrics.recordPipelineSuccess(totalTime);
return {
data: data,
pipeline: pipeline,
success: true
};
} catch (error) {
const totalTime = Date.now() - pipeline.startTime;
this.metrics.recordPipelineError(totalTime);
return {
data: null,
pipeline: pipeline,
success: false,
error: error.message
};
}
}
async processSequentialStage(stage, data, context) {
const timeoutPromise = new Promise((_, reject) => {
setTimeout(() => reject(new Error('Stage timeout')), stage.timeout);
});
const processingPromise = stage.processor(data, context);
return await Promise.race([processingPromise, timeoutPromise]);
}
async processParallelStage(stage, data, context) {
if (!Array.isArray(data)) {
throw new Error('Parallel stage requires array input');
}
// 分批处理以控制并发
const results = [];
const chunks = this.chunkArray(data, stage.concurrency);
for (const chunk of chunks) {
const chunkPromises = chunk.map(item =>
this.processSequentialStage(stage, item, context)
);
const chunkResults = await Promise.all(chunkPromises);
results.push(...chunkResults);
}
return results;
}
chunkArray(array, chunkSize) {
const chunks = [];
for (let i = 0; i < array.length; i += chunkSize) {
chunks.push(array.slice(i, i + chunkSize));
}
return chunks;
}
generatePipelineId() {
return `pipeline_${Date.now()}_${Math.random().toString(36).substring(2)}`;
}
}
// 批处理指标收集器
class BatchMetrics {
constructor() {
this.metrics = {
totalBatches: 0,
totalItems: 0,
totalProcessingTime: 0,
errors: 0,
batchSizes: [],
processingTimes: []
};
}
recordBatch(size, processingTime) {
this.metrics.totalBatches++;
this.metrics.totalItems += size;
this.metrics.totalProcessingTime += processingTime;
this.metrics.batchSizes.push(size);
this.metrics.processingTimes.push(processingTime);
// 保持最近的记录
if (this.metrics.batchSizes.length > 1000) {
this.metrics.batchSizes.shift();
this.metrics.processingTimes.shift();
}
}
recordError() {
this.metrics.errors++;
}
getStats() {
const avgBatchSize = this.metrics.batchSizes.length > 0
? this.metrics.batchSizes.reduce((a, b) => a + b, 0) / this.metrics.batchSizes.length
: 0;
const avgProcessingTime = this.metrics.processingTimes.length > 0
? this.metrics.processingTimes.reduce((a, b) => a + b, 0) / this.metrics.processingTimes.length
: 0;
return {
totalBatches: this.metrics.totalBatches,
totalItems: this.metrics.totalItems,
averageBatchSize: avgBatchSize.toFixed(2),
averageProcessingTime: avgProcessingTime.toFixed(2) + 'ms',
throughput: this.metrics.totalItems / (this.metrics.totalProcessingTime / 1000),
errorRate: (this.metrics.errors / this.metrics.totalBatches * 100).toFixed(2) + '%'
};
}
}
RESTful API设计规范:
// API设计规范检查器
class APIDesignValidator {
constructor() {
this.rules = [
{ name: 'http_methods', check: this.validateHTTPMethods },
{ name: 'url_structure', check: this.validateURLStructure },
{ name: 'response_format', check: this.validateResponseFormat },
{ name: 'error_handling', check: this.validateErrorHandling },
{ name: 'versioning', check: this.validateVersioning },
{ name: 'security', check: this.validateSecurity }
];
}
validate(apiSpec) {
const results = {
passed: 0,
failed: 0,
warnings: 0,
details: []
};
for (const rule of this.rules) {
try {
const result = rule.check.call(this, apiSpec);
results.details.push({
rule: rule.name,
status: result.status,
message: result.message,
suggestions: result.suggestions || []
});
if (result.status === 'pass') {
results.passed++;
} else if (result.status === 'fail') {
results.failed++;
} else {
results.warnings++;
}
} catch (error) {
results.details.push({
rule: rule.name,
status: 'error',
message: `Validation error: ${error.message}`
});
results.failed++;
}
}
return results;
}
validateHTTPMethods(apiSpec) {
const recommendations = {
'GET': '用于获取资源',
'POST': '用于创建资源',
'PUT': '用于完整更新资源',
'PATCH': '用于部分更新资源',
'DELETE': '用于删除资源'
};
const issues = [];
for (const endpoint of apiSpec.endpoints) {
const method = endpoint.method.toUpperCase();
const path = endpoint.path;
// 检查GET请求不应该有请求体
if (method === 'GET' && endpoint.requestBody) {
issues.push(`GET ${path} 不应该包含请求体`);
}
// 检查POST用于集合资源
if (method === 'POST' && !this.isCollectionResource(path)) {
issues.push(`POST ${path} 应该用于集合资源`);
}
// 检查PUT/DELETE用于具体资源
if (['PUT', 'DELETE'].includes(method) && this.isCollectionResource(path)) {
issues.push(`${method} ${path} 应该用于具体资源,而非集合`);
}
}
return {
status: issues.length === 0 ? 'pass' : 'fail',
message: issues.length === 0 ? 'HTTP方法使用规范' : `发现${issues.length}个HTTP方法问题`,
suggestions: issues
};
}
validateURLStructure(apiSpec) {
const issues = [];
for (const endpoint of apiSpec.endpoints) {
const path = endpoint.path;
// 检查URL使用名词而非动词
const pathSegments = path.split('/').filter(seg => seg && !seg.startsWith('{'));
for (const segment of pathSegments) {
if (this.isVerb(segment)) {
issues.push(`路径 ${path} 包含动词 "${segment}",应使用名词`);
}
}
// 检查复数形式
if (this.isCollectionResource(path)) {
const resourceName = this.getResourceName(path);
if (!this.isPlural(resourceName)) {
issues.push(`集合资源 ${path} 应使用复数形式`);
}
}
// 检查URL深度
const depth = pathSegments.length;
if (depth > 3) {
issues.push(`路径 ${path} 层级过深(${depth}层),建议不超过3层`);
}
// 检查命名规范
if (!/^[a-z0-9\-\/{}]+$/.test(path)) {
issues.push(`路径 ${path} 应使用小写字母和连字符`);
}
}
return {
status: issues.length === 0 ? 'pass' : 'warn',
message: issues.length === 0 ? 'URL结构规范' : `发现${issues.length}个URL结构问题`,
suggestions: issues
};
}
validateResponseFormat(apiSpec) {
const issues = [];
for (const endpoint of apiSpec.endpoints) {
// 检查响应状态码
if (!endpoint.responses) {
issues.push(`${endpoint.method} ${endpoint.path} 缺少响应定义`);
continue;
}
// 检查成功响应
const hasSuccessResponse = Object.keys(endpoint.responses)
.some(code => code.startsWith('2'));
if (!hasSuccessResponse) {
issues.push(`${endpoint.method} ${endpoint.path} 缺少2xx成功响应`);
}
// 检查错误响应
const hasErrorResponse = Object.keys(endpoint.responses)
.some(code => code.startsWith('4') || code.startsWith('5'));
if (!hasErrorResponse) {
issues.push(`${endpoint.method} ${endpoint.path} 缺少错误响应定义`);
}
// 检查响应格式一致性
for (const [statusCode, response] of Object.entries(endpoint.responses)) {
if (response.content && !response.content['application/json']) {
issues.push(`${endpoint.method} ${endpoint.path} 响应${statusCode}应支持JSON格式`);
}
}
}
return {
status: issues.length === 0 ? 'pass' : 'fail',
message: issues.length === 0 ? '响应格式规范' : `发现${issues.length}个响应格式问题`,
suggestions: issues
};
}
validateErrorHandling(apiSpec) {
const requiredErrorCodes = ['400', '401', '403', '404', '500'];
const issues = [];
const allErrorCodes = new Set();
for (const endpoint of apiSpec.endpoints) {
if (endpoint.responses) {
Object.keys(endpoint.responses)
.filter(code => code.startsWith('4') || code.startsWith('5'))
.forEach(code => allErrorCodes.add(code));
}
}
// 检查是否定义了标准错误码
for (const requiredCode of requiredErrorCodes) {
if (!allErrorCodes.has(requiredCode)) {
issues.push(`缺少标准错误码 ${requiredCode} 的定义`);
}
}
// 检查错误响应格式
for (const endpoint of apiSpec.endpoints) {
if (endpoint.responses) {
for (const [code, response] of Object.entries(endpoint.responses)) {
if ((code.startsWith('4') || code.startsWith('5')) && response.content) {
const jsonContent = response.content['application/json'];
if (jsonContent && jsonContent.schema) {
const schema = jsonContent.schema;
if (!schema.properties || !schema.properties.error) {
issues.push(`${endpoint.method} ${endpoint.path} 错误响应${code}应包含error字段`);
}
}
}
}
}
}
return {
status: issues.length === 0 ? 'pass' : 'warn',
message: issues.length === 0 ? '错误处理规范' : `发现${issues.length}个错误处理问题`,
suggestions: issues
};
}
validateVersioning(apiSpec) {
const issues = [];
// 检查版本策略
if (!apiSpec.version && !apiSpec.info?.version) {
issues.push('API规范中缺少版本信息');
}
// 检查URL版本策略
const hasURLVersioning = apiSpec.endpoints.some(endpoint =>
endpoint.path.includes('/v1/') || endpoint.path.includes('/v2/')
);
const hasHeaderVersioning = apiSpec.endpoints.some(endpoint =>
endpoint.parameters?.some(param =>
param.name.toLowerCase() === 'api-version'
)
);
if (!hasURLVersioning && !hasHeaderVersioning) {
issues.push('建议明确API版本策略(URL版本化或请求头版本化)');
}
return {
status: issues.length === 0 ? 'pass' : 'warn',
message: issues.length === 0 ? '版本控制规范' : '版本控制需要完善',
suggestions: issues
};
}
validateSecurity(apiSpec) {
const issues = [];
// 检查安全定义
if (!apiSpec.security && !apiSpec.components?.securitySchemes) {
issues.push('缺少安全认证定义');
}
// 检查敏感操作的安全要求
for (const endpoint of apiSpec.endpoints) {
const isSensitiveOperation = ['POST', 'PUT', 'PATCH', 'DELETE']
.includes(endpoint.method.toUpperCase());
if (isSensitiveOperation && !endpoint.security) {
issues.push(`${endpoint.method} ${endpoint.path} 敏感操作缺少安全认证`);
}
}
return {
status: issues.length === 0 ? 'pass' : 'fail',
message: issues.length === 0 ? '安全定义规范' : `发现${issues.length}个安全问题`,
suggestions: issues
};
}
// 辅助方法
isCollectionResource(path) {
return !path.includes('{') || path.lastIndexOf('{') < path.lastIndexOf('/');
}
getResourceName(path) {
const segments = path.split('/').filter(seg => seg && !seg.startsWith('{'));
return segments[segments.length - 1];
}
isVerb(word) {
const commonVerbs = ['get', 'post', 'put', 'delete', 'create', 'update', 'remove', 'add'];
return commonVerbs.includes(word.toLowerCase());
}
isPlural(word) {
return word.endsWith('s') || word.endsWith('es') || word.endsWith('ies');
}
}
标准化错误响应:
// 统一错误处理器
class UnifiedErrorHandler {
constructor() {
this.errorCodes = new Map();
this.initializeStandardErrors();
}
initializeStandardErrors() {
// 客户端错误 4xx
this.registerError('VALIDATION_ERROR', {
httpStatus: 400,
code: 'VALIDATION_ERROR',
message: '请求参数验证失败',
category: 'CLIENT_ERROR'
});
this.registerError('AUTHENTICATION_REQUIRED', {
httpStatus: 401,
code: 'AUTHENTICATION_REQUIRED',
message: '需要身份认证',
category: 'CLIENT_ERROR'
});
this.registerError('INSUFFICIENT_PERMISSIONS', {
httpStatus: 403,
code: 'INSUFFICIENT_PERMISSIONS',
message: '权限不足',
category: 'CLIENT_ERROR'
});
this.registerError('RESOURCE_NOT_FOUND', {
httpStatus: 404,
code: 'RESOURCE_NOT_FOUND',
message: '请求的资源不存在',
category: 'CLIENT_ERROR'
});
this.registerError('METHOD_NOT_ALLOWED', {
httpStatus: 405,
code: 'METHOD_NOT_ALLOWED',
message: '请求方法不被允许',
category: 'CLIENT_ERROR'
});
this.registerError('RATE_LIMIT_EXCEEDED', {
httpStatus: 429,
code: 'RATE_LIMIT_EXCEEDED',
message: '请求频率超过限制',
category: 'CLIENT_ERROR'
});
// 服务器错误 5xx
this.registerError('INTERNAL_SERVER_ERROR', {
httpStatus: 500,
code: 'INTERNAL_SERVER_ERROR',
message: '服务器内部错误',
category: 'SERVER_ERROR'
});
this.registerError('SERVICE_UNAVAILABLE', {
httpStatus: 503,
code: 'SERVICE_UNAVAILABLE',
message: '服务暂不可用',
category: 'SERVER_ERROR'
});
this.registerError('GATEWAY_TIMEOUT', {
httpStatus: 504,
code: 'GATEWAY_TIMEOUT',
message: '网关超时',
category: 'SERVER_ERROR'
});
}
registerError(errorCode, errorDef) {
this.errorCodes.set(errorCode, errorDef);
}
createError(errorCode, details = {}, cause = null) {
const errorDef = this.errorCodes.get(errorCode);
if (!errorDef) {
throw new Error(`Unknown error code: ${errorCode}`);
}
return new APIError({
httpStatus: errorDef.httpStatus,
code: errorCode,
message: details.message || errorDef.message,
category: errorDef.category,
details: details,
cause: cause,
timestamp: new Date().toISOString(),
traceId: this.generateTraceId()
});
}
handleError(error, request, response) {
let apiError;
if (error instanceof APIError) {
apiError = error;
} else {
// 转换原生错误为API错误
apiError = this.convertToAPIError(error);
}
// 记录错误日志
this.logError(apiError, request);
// 构建错误响应
const errorResponse = this.buildErrorResponse(apiError);
// 设置响应头
response.setHeader('Content-Type', 'application/json');
response.setHeader('X-Error-Code', apiError.code);
response.setHeader('X-Trace-Id', apiError.traceId);
// 发送错误响应
response.status(apiError.httpStatus).json(errorResponse);
}
convertToAPIError(error) {
if (error.name === 'ValidationError') {
return this.createError('VALIDATION_ERROR', {
message: error.message,
fields: error.details
}, error);
}
if (error.name === 'UnauthorizedError') {
return this.createError('AUTHENTICATION_REQUIRED', {
message: error.message
}, error);
}
if (error.name === 'ForbiddenError') {
return this.createError('INSUFFICIENT_PERMISSIONS', {
message: error.message
}, error);
}
if (error.name === 'NotFoundError') {
return this.createError('RESOURCE_NOT_FOUND', {
message: error.message
}, error);
}
// 默认转换为服务器错误
return this.createError('INTERNAL_SERVER_ERROR', {
message: error.message || '未知错误'
}, error);
}
buildErrorResponse(apiError) {
const response = {
error: {
code: apiError.code,
message: apiError.message,
category: apiError.category,
timestamp: apiError.timestamp,
traceId: apiError.traceId
}
};
// 添加详细信息(仅在开发环境)
if (process.env.NODE_ENV === 'development' && apiError.details) {
response.error.details = apiError.details;
}
// 添加堆栈跟踪(仅在开发环境)
if (process.env.NODE_ENV === 'development' && apiError.cause) {
response.error.stack = apiError.cause.stack;
}
return response;
}
logError(apiError, request) {
const logEntry = {
timestamp: apiError.timestamp,
traceId: apiError.traceId,
level: apiError.category === 'SERVER_ERROR' ? 'ERROR' : 'WARN',
code: apiError.code,
message: apiError.message,
request: {
method: request.method,
url: request.url,
headers: this.sanitizeHeaders(request.headers),
userAgent: request.headers['user-agent'],
ip: request.ip
}
};
if (apiError.details) {
logEntry.details = apiError.details;
}
if (apiError.cause) {
logEntry.originalError = {
name: apiError.cause.name,
message: apiError.cause.message,
stack: apiError.cause.stack
};
}
console.error(JSON.stringify(logEntry, null, 2));
}
sanitizeHeaders(headers) {
const sanitized = { ...headers };
// 移除敏感信息
const sensitiveHeaders = ['authorization', 'cookie', 'x-api-key'];
for (const header of sensitiveHeaders) {
if (sanitized[header]) {
sanitized[header] = '[REDACTED]';
}
}
return sanitized;
}
generateTraceId() {
return `${Date.now()}-${Math.random().toString(36).substring(2)}`;
}
}
// API错误类
class APIError extends Error {
constructor(config) {
super(config.message);
this.name = 'APIError';
this.httpStatus = config.httpStatus;
this.code = config.code;
this.category = config.category;
this.details = config.details;
this.cause = config.cause;
this.timestamp = config.timestamp;
this.traceId = config.traceId;
Error.captureStackTrace(this, APIError);
}
toJSON() {
return {
name: this.name,
message: this.message,
httpStatus: this.httpStatus,
code: this.code,
category: this.category,
details: this.details,
timestamp: this.timestamp,
traceId: this.traceId
};
}
}
自动化文档生成:
// OpenAPI文档生成器
class OpenAPIDocumentGenerator {
constructor() {
this.spec = {
openapi: '3.0.3',
info: {
title: 'API Gateway',
version: '1.0.0',
description: 'API Gateway服务接口文档'
},
servers: [],
paths: {},
components: {
schemas: {},
securitySchemes: {},
responses: {}
}
};
this.initializeCommonComponents();
}
initializeCommonComponents() {
// 通用安全方案
this.spec.components.securitySchemes = {
BearerAuth: {
type: 'http',
scheme: 'bearer',
bearerFormat: 'JWT'
},
ApiKeyAuth: {
type: 'apiKey',
in: 'header',
name: 'X-API-Key'
},
OAuth2: {
type: 'oauth2',
flows: {
authorizationCode: {
authorizationUrl: '/oauth/authorize',
tokenUrl: '/oauth/token',
scopes: {
read: '读取权限',
write: '写入权限',
admin: '管理权限'
}
}
}
}
};
// 通用响应模板
this.spec.components.responses = {
UnauthorizedError: {
description: '认证失败',
content: {
'application/json': {
schema: {
$ref: '#/components/schemas/ErrorResponse'
}
}
}
},
InternalServerError: {
description: '服务器内部错误',
content: {
'application/json': {
schema: {
$ref: '#/components/schemas/ErrorResponse'
}
}
}
}
};
// 通用数据模式
this.spec.components.schemas = {
ErrorResponse: {
type: 'object',
required: ['error'],
properties: {
error: {
type: 'object',
required: ['code', 'message', 'timestamp'],
properties: {
code: {
type: 'string',
description: '错误代码'
},
message: {
type: 'string',
description: '错误描述'
},
category: {
type: 'string',
enum: ['CLIENT_ERROR', 'SERVER_ERROR'],
description: '错误类别'
},
timestamp: {
type: 'string',
format: 'date-time',
description: '错误发生时间'
},
traceId: {
type: 'string',
description: '追踪ID'
},
details: {
type: 'object',
description: '错误详细信息'
}
}
}
}
},
PaginationRequest: {
type: 'object',
properties: {
page: {
type: 'integer',
minimum: 1,
default: 1,
description: '页码'
},
size: {
type: 'integer',
minimum: 1,
maximum: 100,
default: 20,
description: '每页数量'
},
sort: {
type: 'string',
description: '排序字段'
},
order: {
type: 'string',
enum: ['asc', 'desc'],
default: 'desc',
description: '排序方向'
}
}
},
PaginationResponse: {
type: 'object',
required: ['data', 'pagination'],
properties: {
data: {
type: 'array',
description: '数据列表'
},
pagination: {
type: 'object',
required: ['page', 'size', 'total', 'pages'],
properties: {
page: {
type: 'integer',
description: '当前页码'
},
size: {
type: 'integer',
description: '每页数量'
},
total: {
type: 'integer',
description: '总记录数'
},
pages: {
type: 'integer',
description: '总页数'
}
}
}
}
}
};
}
addEndpoint(path, method, definition) {
if (!this.spec.paths[path]) {
this.spec.paths[path] = {};
}
// 增强端点定义
const enhancedDefinition = {
...definition,
responses: this.enhanceResponses(definition.responses || {}),
security: definition.security || [{ BearerAuth: [] }]
};
this.spec.paths[path][method.toLowerCase()] = enhancedDefinition;
}
enhanceResponses(responses) {
const enhanced = { ...responses };
// 自动添加通用错误响应
if (!enhanced['401']) {
enhanced['401'] = { $ref: '#/components/responses/UnauthorizedError' };
}
if (!enhanced['403']) {
enhanced['403'] = { $ref: '#/components/responses/ForbiddenError' };
}
if (!enhanced['500']) {
enhanced['500'] = { $ref: '#/components/responses/InternalServerError' };
}
return enhanced;
}
addSchema(name, schema) {
this.spec.components.schemas[name] = schema;
}
generateFromRoutes(routes) {
for (const route of routes) {
const definition = {
summary: route.summary || `${route.method.toUpperCase()} ${route.path}`,
description: route.description,
tags: route.tags || ['API'],
parameters: this.extractParameters(route),
requestBody: this.extractRequestBody(route),
responses: this.extractResponses(route)
};
this.addEndpoint(route.path, route.method, definition);
}
}
extractParameters(route) {
const parameters = [];
// 路径参数
const pathParams = route.path.match(/\{([^}]+)\}/g);
if (pathParams) {
pathParams.forEach(param => {
const paramName = param.slice(1, -1);
parameters.push({
name: paramName,
in: 'path',
required: true,
schema: { type: 'string' },
description: `${paramName} ID`
});
});
}
// 查询参数
if (route.queryParams) {
route.queryParams.forEach(param => {
parameters.push({
name: param.name,
in: 'query',
required: param.required || false,
schema: { type: param.type || 'string' },
description: param.description
});
});
}
return parameters;
}
extractRequestBody(route) {
if (!route.requestBody) return undefined;
return {
required: route.requestBody.required || true,
content: {
'application/json': {
schema: route.requestBody.schema || { type: 'object' }
}
}
};
}
extractResponses(route) {
const responses = {};
// 默认成功响应
const successCode = route.method.toLowerCase() === 'post' ? '201' : '200';
responses[successCode] = {
description: '操作成功',
content: {
'application/json': {
schema: route.responseSchema || { type: 'object' }
}
}
};
// 合并自定义响应
if (route.responses) {
Object.assign(responses, route.responses);
}
return responses;
}
setInfo(info) {
this.spec.info = { ...this.spec.info, ...info };
}
addServer(server) {
this.spec.servers.push(server);
}
export() {
return JSON.stringify(this.spec, null, 2);
}
exportYAML() {
const yaml = require('js-yaml');
return yaml.dump(this.spec);
}
generateHTML() {
return `
${this.spec.info.title} - API文档
`;
}
}
// 使用示例
const docGenerator = new OpenAPIDocumentGenerator();
docGenerator.setInfo({
title: 'API网关服务',
version: '2.0.0',
description: '企业级API网关服务接口文档',
contact: {
name: 'API Support',
email: '[email protected]'
},
license: {
name: 'MIT',
url: 'https://opensource.org/licenses/MIT'
}
});
docGenerator.addServer({
url: 'https://api.example.com/v1',
description: '生产环境'
});
docGenerator.addServer({
url: 'https://staging-api.example.com/v1',
description: '测试环境'
});
关键词:API网关、微服务架构、服务治理、性能优化、安全认证、负载均衡、监控运维、云原生、数字化转型