跳到主要内容

API设计与实现

目录

概述

API设计与实现是构建现代Web应用的核心环节,涉及接口规范、数据模型、认证授权、错误处理、性能优化等多个方面。良好的API设计能够提高开发效率,降低维护成本,提升系统可靠性。

设计原则

1. RESTful设计原则

  • 资源导向:以资源为中心设计URL结构
  • HTTP语义:正确使用HTTP方法和状态码
  • 无状态:每个请求包含完整信息
  • 统一接口:标准化的请求响应格式

2. 一致性原则

  • 命名规范:统一的命名约定
  • 响应格式:标准化的数据结构
  • 错误处理:一致的错误码和消息
  • 版本控制:向后兼容的版本策略

接口设计

1. URL设计规范

// URL设计示例
const API_ENDPOINTS = {
// 用户管理
users: {
list: '/api/v1/users',
detail: (id) => `/api/v1/users/${id}`,
create: '/api/v1/users',
update: (id) => `/api/v1/users/${id}`,
delete: (id) => `/api/v1/users/${id}`,
posts: (id) => `/api/v1/users/${id}/posts`
},

// 文章管理
posts: {
list: '/api/v1/posts',
detail: (id) => `/api/v1/posts/${id}`,
create: '/api/v1/posts',
update: (id) => `/api/v1/posts/${id}`,
delete: (id) => `/api/v1/posts/${id}`,
comments: (id) => `/api/v1/posts/${id}/comments`
},

// 认证相关
auth: {
login: '/api/v1/auth/login',
register: '/api/v1/auth/register',
refresh: '/api/v1/auth/refresh',
logout: '/api/v1/auth/logout'
}
};

2. HTTP方法使用

// HTTP方法使用规范
class HTTPMethodHandler {
// GET: 获取资源
static async get(endpoint, params = {}) {
const queryString = new URLSearchParams(params).toString();
const url = queryString ? `${endpoint}?${queryString}` : endpoint;

const response = await fetch(url, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${this.getAuthToken()}`
}
});

return this.handleResponse(response);
}

// POST: 创建资源
static async post(endpoint, data = {}) {
const response = await fetch(endpoint, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${this.getAuthToken()}`
},
body: JSON.stringify(data)
});

return this.handleResponse(response);
}

// PUT: 完整更新资源
static async put(endpoint, data = {}) {
const response = await fetch(endpoint, {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${this.getAuthToken()}`
},
body: JSON.stringify(data)
});

return this.handleResponse(response);
}

// PATCH: 部分更新资源
static async patch(endpoint, data = {}) {
const response = await fetch(endpoint, {
method: 'PATCH',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${this.getAuthToken()}`
},
body: JSON.stringify(data)
});

return this.handleResponse(response);
}

// DELETE: 删除资源
static async delete(endpoint) {
const response = await fetch(endpoint, {
method: 'DELETE',
headers: {
'Authorization': `Bearer ${this.getAuthToken()}`
}
});

return this.handleResponse(response);
}

// 响应处理
static async handleResponse(response) {
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}

const contentType = response.headers.get('content-type');
if (contentType && contentType.includes('application/json')) {
return await response.json();
}

return await response.text();
}

// 获取认证token
static getAuthToken() {
return localStorage.getItem('auth_token') || '';
}
}

3. 查询参数设计

// 查询参数处理
class QueryParameterHandler {
// 分页参数
static getPaginationParams(page = 1, pageSize = 10) {
return {
page: Math.max(1, parseInt(page)),
pageSize: Math.min(100, Math.max(1, parseInt(pageSize)))
};
}

// 排序参数
static getSortParams(sortBy = 'createdAt', sortOrder = 'desc') {
const validSortOrders = ['asc', 'desc'];
const order = validSortOrders.includes(sortOrder) ? sortOrder : 'desc';

return {
sortBy: sortBy,
sortOrder: order
};
}

// 过滤参数
static getFilterParams(filters = {}) {
const validFilters = {};

Object.keys(filters).forEach(key => {
if (filters[key] !== undefined && filters[key] !== null && filters[key] !== '') {
validFilters[key] = filters[key];
}
});

return validFilters;
}

// 搜索参数
static getSearchParams(query = '', fields = []) {
if (!query || !fields.length) {
return {};
}

return {
search: query,
searchFields: fields.join(',')
};
}

// 构建查询字符串
static buildQueryString(params = {}) {
const queryParams = new URLSearchParams();

Object.keys(params).forEach(key => {
if (params[key] !== undefined && params[key] !== null) {
if (Array.isArray(params[key])) {
params[key].forEach(value => queryParams.append(key, value));
} else {
queryParams.append(key, params[key]);
}
}
});

return queryParams.toString();
}
}

数据模型设计

1. 请求数据验证

// 数据验证器
class DataValidator {
// 用户创建验证
static validateUserCreate(data) {
const errors = [];

// 用户名验证
if (!data.name || data.name.trim().length < 2) {
errors.push({ field: 'name', message: '用户名至少2个字符' });
}

// 邮箱验证
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (!data.email || !emailRegex.test(data.email)) {
errors.push({ field: 'email', message: '请输入有效的邮箱地址' });
}

// 密码验证
if (!data.password || data.password.length < 6) {
errors.push({ field: 'password', message: '密码至少6个字符' });
}

return {
isValid: errors.length === 0,
errors: errors
};
}

// 文章创建验证
static validatePostCreate(data) {
const errors = [];

// 标题验证
if (!data.title || data.title.trim().length < 5) {
errors.push({ field: 'title', message: '标题至少5个字符' });
}

// 内容验证
if (!data.content || data.content.trim().length < 10) {
errors.push({ field: 'content', message: '内容至少10个字符' });
}

// 分类验证
if (!data.categoryId) {
errors.push({ field: 'categoryId', message: '请选择文章分类' });
}

return {
isValid: errors.length === 0,
errors: errors
};
}

// 通用字符串验证
static validateString(value, fieldName, minLength = 1, maxLength = 255) {
if (!value || typeof value !== 'string') {
return { field: fieldName, message: `${fieldName}必须是字符串` };
}

const trimmedValue = value.trim();
if (trimmedValue.length < minLength) {
return { field: fieldName, message: `${fieldName}至少${minLength}个字符` };
}

if (trimmedValue.length > maxLength) {
return { field: fieldName, message: `${fieldName}最多${maxLength}个字符` };
}

return null;
}
}

2. 响应数据格式化

// 响应数据格式化器
class ResponseFormatter {
// 成功响应
static success(data, message = '操作成功') {
return {
success: true,
code: 200,
message: message,
data: data,
timestamp: new Date().toISOString()
};
}

// 分页响应
static paginated(data, page, pageSize, total) {
return {
success: true,
code: 200,
message: '获取成功',
data: {
list: data,
pagination: {
page: parseInt(page),
pageSize: parseInt(pageSize),
total: parseInt(total),
totalPages: Math.ceil(total / pageSize),
hasNext: page * pageSize < total,
hasPrev: page > 1
}
},
timestamp: new Date().toISOString()
};
}

// 错误响应
static error(code, message, details = null) {
return {
success: false,
code: code,
message: message,
details: details,
timestamp: new Date().toISOString()
};
}

// 验证错误响应
static validationError(errors) {
return {
success: false,
code: 422,
message: '数据验证失败',
details: errors,
timestamp: new Date().toISOString()
};
}
}

认证与授权

1. JWT认证实现

// JWT认证服务
class JWTAuthService {
constructor(secretKey, options = {}) {
this.secretKey = secretKey;
this.options = {
expiresIn: options.expiresIn || '24h',
issuer: options.issuer || 'api-service',
audience: options.audience || 'web-app',
...options
};
}

// 生成访问token
generateAccessToken(payload) {
const token = jwt.sign(payload, this.secretKey, {
expiresIn: this.options.expiresIn,
issuer: this.options.issuer,
audience: this.options.audience
});

return {
access_token: token,
token_type: 'Bearer',
expires_in: 86400, // 24小时
expires_at: new Date(Date.now() + 86400 * 1000).toISOString()
};
}

// 生成刷新token
generateRefreshToken(payload) {
const refreshToken = jwt.sign(payload, this.secretKey, {
expiresIn: '7d', // 7天
issuer: this.options.issuer,
audience: this.options.audience
});

return refreshToken;
}

// 验证token
verifyToken(token) {
try {
const decoded = jwt.verify(token, this.secretKey, {
issuer: this.options.issuer,
audience: this.options.audience
});

return {
valid: true,
payload: decoded,
expired: false
};
} catch (error) {
return {
valid: false,
payload: null,
expired: error.name === 'TokenExpiredError',
error: error.message
};
}
}

// 刷新token
refreshAccessToken(refreshToken) {
const verification = this.verifyToken(refreshToken);

if (!verification.valid) {
throw new Error('无效的刷新token');
}

if (verification.expired) {
throw new Error('刷新token已过期');
}

// 生成新的访问token
const payload = verification.payload;
delete payload.iat;
delete payload.exp;

return this.generateAccessToken(payload);
}
}

2. 权限控制中间件

// 权限控制中间件
const authMiddleware = {
// 验证token
authenticate: (req, res, next) => {
const authHeader = req.headers.authorization;

if (!authHeader || !authHeader.startsWith('Bearer ')) {
return res.status(401).json(
ResponseFormatter.error(401, '缺少认证token')
);
}

const token = authHeader.substring(7);
const authService = new JWTAuthService(process.env.JWT_SECRET);
const verification = authService.verifyToken(token);

if (!verification.valid) {
return res.status(401).json(
ResponseFormatter.error(401, '无效的认证token')
);
}

if (verification.expired) {
return res.status(401).json(
ResponseFormatter.error(401, '认证token已过期')
);
}

req.user = verification.payload;
next();
},

// 角色权限验证
authorize: (roles) => {
return (req, res, next) => {
if (!req.user) {
return res.status(401).json(
ResponseFormatter.error(401, '用户未认证')
);
}

if (!roles.includes(req.user.role)) {
return res.status(403).json(
ResponseFormatter.error(403, '权限不足')
);
}

next();
};
},

// 资源所有者验证
authorizeOwner: (resourceModel, resourceIdField = 'id') => {
return async (req, res, next) => {
try {
const resourceId = req.params[resourceIdField];
const resource = await resourceModel.findById(resourceId);

if (!resource) {
return res.status(404).json(
ResponseFormatter.error(404, '资源不存在')
);
}

if (resource.userId.toString() !== req.user.id) {
return res.status(403).json(
ResponseFormatter.error(403, '只能操作自己的资源')
);
}

req.resource = resource;
next();
} catch (error) {
return res.status(500).json(
ResponseFormatter.error(500, '权限验证失败')
);
}
};
}
};

错误处理

1. 统一错误处理

// 自定义错误类
class APIError extends Error {
constructor(code, message, details = null) {
super(message);
this.name = 'APIError';
this.code = code;
this.details = details;
this.timestamp = new Date().toISOString();
}
}

// 错误码定义
const ErrorCodes = {
// 客户端错误 (4xx)
BAD_REQUEST: 400,
UNAUTHORIZED: 401,
FORBIDDEN: 403,
NOT_FOUND: 404,
METHOD_NOT_ALLOWED: 405,
CONFLICT: 409,
VALIDATION_ERROR: 422,
TOO_MANY_REQUESTS: 429,

// 服务端错误 (5xx)
INTERNAL_ERROR: 500,
NOT_IMPLEMENTED: 501,
SERVICE_UNAVAILABLE: 503,
GATEWAY_TIMEOUT: 504
};

// 错误处理中间件
const errorHandler = (error, req, res, next) => {
console.error('API错误:', {
message: error.message,
stack: error.stack,
url: req.url,
method: req.method,
user: req.user?.id
});

// API错误处理
if (error instanceof APIError) {
return res.status(error.code).json(
ResponseFormatter.error(error.code, error.message, error.details)
);
}

// 验证错误处理
if (error.name === 'ValidationError') {
const validationErrors = Object.keys(error.errors).map(key => ({
field: key,
message: error.errors[key].message,
value: error.errors[key].value
}));

return res.status(422).json(
ResponseFormatter.validationError(validationErrors)
);
}

// 数据库错误处理
if (error.code === 'ER_DUP_ENTRY') {
return res.status(409).json(
ResponseFormatter.error(409, '数据已存在')
);
}

if (error.code === 'ER_NO_REFERENCED_ROW') {
return res.status(400).json(
ResponseFormatter.error(400, '关联数据不存在')
);
}

// 默认错误处理
return res.status(500).json(
ResponseFormatter.error(500, '服务器内部错误')
);
};

// 404错误处理
const notFoundHandler = (req, res) => {
res.status(404).json(
ResponseFormatter.error(404, `接口 ${req.method} ${req.url} 不存在`)
);
};

2. 业务错误处理

// 业务错误处理器
class BusinessErrorHandler {
// 用户相关错误
static handleUserError(error) {
switch (error.code) {
case 'USER_NOT_FOUND':
throw new APIError(404, '用户不存在');
case 'USER_ALREADY_EXISTS':
throw new APIError(409, '用户已存在');
case 'INVALID_PASSWORD':
throw new APIError(401, '密码错误');
case 'ACCOUNT_LOCKED':
throw new APIError(423, '账户已被锁定');
case 'EMAIL_NOT_VERIFIED':
throw new APIError(403, '邮箱未验证');
default:
throw new APIError(500, '用户操作失败');
}
}

// 文章相关错误
static handlePostError(error) {
switch (error.code) {
case 'POST_NOT_FOUND':
throw new APIError(404, '文章不存在');
case 'POST_ACCESS_DENIED':
throw new APIError(403, '无权访问此文章');
case 'POST_ALREADY_PUBLISHED':
throw new APIError(409, '文章已发布');
default:
throw new APIError(500, '文章操作失败');
}
}

// 文件上传错误
static handleFileUploadError(error) {
switch (error.code) {
case 'FILE_TOO_LARGE':
throw new APIError(413, '文件过大');
case 'INVALID_FILE_TYPE':
throw new APIError(400, '不支持的文件类型');
case 'UPLOAD_FAILED':
throw new APIError(500, '文件上传失败');
default:
throw new APIError(500, '文件操作失败');
}
}
}

性能优化

1. 缓存策略

// 缓存管理器
class CacheManager {
constructor() {
this.cache = new Map();
this.ttl = new Map(); // 过期时间
}

// 设置缓存
set(key, value, ttlSeconds = 300) {
const expiresAt = Date.now() + ttlSeconds * 1000;

this.cache.set(key, value);
this.ttl.set(key, expiresAt);

// 清理过期缓存
this.cleanup();
}

// 获取缓存
get(key) {
if (!this.cache.has(key)) {
return null;
}

const expiresAt = this.ttl.get(key);
if (Date.now() > expiresAt) {
this.cache.delete(key);
this.ttl.delete(key);
return null;
}

return this.cache.get(key);
}

// 删除缓存
delete(key) {
this.cache.delete(key);
this.ttl.delete(key);
}

// 清理过期缓存
cleanup() {
const now = Date.now();

for (const [key, expiresAt] of this.ttl.entries()) {
if (now > expiresAt) {
this.cache.delete(key);
this.ttl.delete(key);
}
}
}

// 清空所有缓存
clear() {
this.cache.clear();
this.ttl.clear();
}
}

// 缓存中间件
const cacheMiddleware = (ttlSeconds = 300) => {
const cacheManager = new CacheManager();

return (req, res, next) => {
// 只缓存GET请求
if (req.method !== 'GET') {
return next();
}

const cacheKey = `${req.method}:${req.url}`;
const cachedResponse = cacheManager.get(cacheKey);

if (cachedResponse) {
return res.json(cachedResponse);
}

// 重写res.json方法以缓存响应
const originalJson = res.json;
res.json = function(data) {
cacheManager.set(cacheKey, data, ttlSeconds);
return originalJson.call(this, data);
};

next();
};
};

2. 数据库查询优化

// 数据库查询优化器
class QueryOptimizer {
// 分页查询优化
static optimizePagination(query, page, pageSize) {
const skip = (page - 1) * pageSize;
const limit = pageSize;

return query
.skip(skip)
.limit(limit)
.lean(); // 返回普通JavaScript对象,提高性能
}

// 字段选择优化
static optimizeFieldSelection(query, fields) {
if (fields && fields.length > 0) {
const projection = {};
fields.forEach(field => {
projection[field] = 1;
});
return query.select(projection);
}

return query;
}

// 排序优化
static optimizeSorting(query, sortBy, sortOrder) {
if (sortBy) {
const sortDirection = sortOrder === 'desc' ? -1 : 1;
return query.sort({ [sortBy]: sortDirection });
}

return query;
}

// 聚合查询优化
static optimizeAggregation(pipeline) {
// 添加索引提示
if (pipeline.length > 0 && pipeline[0].$match) {
pipeline.unshift({ $hint: { createdAt: 1 } });
}

// 限制结果数量
pipeline.push({ $limit: 1000 });

return pipeline;
}
}

安全防护

1. 输入验证与清理

// 输入验证器
class InputValidator {
// XSS防护
static sanitizeHtml(input) {
if (typeof input !== 'string') {
return input;
}

return input
.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;')
.replace(/'/g, '&#x27;')
.replace(/\//g, '&#x2F;');
}

// SQL注入防护
static sanitizeSql(input) {
if (typeof input !== 'string') {
return input;
}

// 移除危险字符
return input.replace(/['";\\]/g, '');
}

// 文件路径防护
static sanitizePath(input) {
if (typeof input !== 'string') {
return input;
}

// 移除路径遍历攻击
return input.replace(/\.\./g, '').replace(/\/\//g, '/');
}

// 通用输入清理
static sanitizeInput(input, type = 'string') {
switch (type) {
case 'html':
return this.sanitizeHtml(input);
case 'sql':
return this.sanitizeSql(input);
case 'path':
return this.sanitizePath(input);
default:
return input;
}
}
}

// 输入验证中间件
const inputValidationMiddleware = (schema) => {
return (req, res, next) => {
try {
const { error, value } = schema.validate(req.body);

if (error) {
const validationErrors = error.details.map(detail => ({
field: detail.path.join('.'),
message: detail.message,
value: detail.context?.value
}));

return res.status(422).json(
ResponseFormatter.validationError(validationErrors)
);
}

// 清理输入数据
req.body = this.sanitizeObject(value);
next();
} catch (error) {
return res.status(400).json(
ResponseFormatter.error(400, '输入验证失败')
);
}
};
};

2. 限流与防护

// 限流器
class RateLimiter {
constructor(windowMs = 15 * 60 * 1000, maxRequests = 100) {
this.windowMs = windowMs;
this.maxRequests = maxRequests;
this.requests = new Map();
}

// 检查限流
isAllowed(identifier) {
const now = Date.now();
const windowStart = now - this.windowMs;

if (!this.requests.has(identifier)) {
this.requests.set(identifier, []);
}

const userRequests = this.requests.get(identifier);

// 清理过期的请求记录
const validRequests = userRequests.filter(timestamp => timestamp > windowStart);

if (validRequests.length >= this.maxRequests) {
return false;
}

// 添加当前请求
validRequests.push(now);
this.requests.set(identifier, validRequests);

return true;
}

// 获取剩余请求次数
getRemainingRequests(identifier) {
const now = Date.now();
const windowStart = now - this.windowMs;

if (!this.requests.has(identifier)) {
return this.maxRequests;
}

const userRequests = this.requests.get(identifier);
const validRequests = userRequests.filter(timestamp => timestamp > windowStart);

return Math.max(0, this.maxRequests - validRequests.length);
}

// 清理过期数据
cleanup() {
const now = Date.now();
const windowStart = now - this.windowMs;

for (const [identifier, requests] of this.requests.entries()) {
const validRequests = requests.filter(timestamp => timestamp > windowStart);

if (validRequests.length === 0) {
this.requests.delete(identifier);
} else {
this.requests.set(identifier, validRequests);
}
}
}
}

// 限流中间件
const rateLimitMiddleware = (windowMs = 15 * 60 * 1000, maxRequests = 100) => {
const limiter = new RateLimiter(windowMs, maxRequests);

return (req, res, next) => {
const identifier = req.ip || req.headers['x-forwarded-for'] || 'unknown';

if (!limiter.isAllowed(identifier)) {
return res.status(429).json(
ResponseFormatter.error(429, '请求过于频繁,请稍后再试')
);
}

// 添加限流信息到响应头
res.set({
'X-RateLimit-Limit': maxRequests,
'X-RateLimit-Remaining': limiter.getRemainingRequests(identifier),
'X-RateLimit-Reset': new Date(Date.now() + windowMs).toISOString()
});

next();
};
};

测试策略

1. 单元测试

// API接口单元测试
describe('用户API测试', () => {
let app;
let request;

beforeAll(async () => {
app = require('../app');
request = require('supertest')(app);
});

describe('GET /api/v1/users', () => {
it('应该返回用户列表', async () => {
const response = await request
.get('/api/v1/users')
.expect(200);

expect(response.body.success).toBe(true);
expect(response.body.data).toBeDefined();
expect(Array.isArray(response.body.data.list)).toBe(true);
});

it('应该支持分页参数', async () => {
const response = await request
.get('/api/v1/users?page=2&pageSize=5')
.expect(200);

expect(response.body.data.pagination.page).toBe(2);
expect(response.body.data.pagination.pageSize).toBe(5);
});
});

describe('POST /api/v1/users', () => {
it('应该创建新用户', async () => {
const userData = {
name: '测试用户',
email: 'test@example.com',
password: 'password123'
};

const response = await request
.post('/api/v1/users')
.send(userData)
.expect(201);

expect(response.body.success).toBe(true);
expect(response.body.data.name).toBe(userData.name);
expect(response.body.data.email).toBe(userData.email);
});

it('应该验证必填字段', async () => {
const response = await request
.post('/api/v1/users')
.send({})
.expect(422);

expect(response.body.success).toBe(false);
expect(response.body.code).toBe(422);
});
});
});

2. 集成测试

// API集成测试
describe('用户认证流程测试', () => {
let app;
let request;
let testUser;

beforeAll(async () => {
app = require('../app');
request = require('supertest')(app);

// 创建测试用户
testUser = await createTestUser();
});

afterAll(async () => {
await cleanupTestUser(testUser.id);
});

it('应该完成完整的登录流程', async () => {
// 1. 用户登录
const loginResponse = await request
.post('/api/v1/auth/login')
.send({
email: testUser.email,
password: 'password123'
})
.expect(200);

const { access_token } = loginResponse.body.data;

// 2. 使用token访问受保护资源
const userResponse = await request
.get('/api/v1/users/profile')
.set('Authorization', `Bearer ${access_token}`)
.expect(200);

expect(userResponse.body.data.email).toBe(testUser.email);

// 3. 刷新token
const refreshResponse = await request
.post('/api/v1/auth/refresh')
.send({
refresh_token: loginResponse.body.data.refresh_token
})
.expect(200);

expect(refreshResponse.body.data.access_token).toBeDefined();
});
});

部署与监控

1. 环境配置

// 环境配置管理
class EnvironmentConfig {
constructor() {
this.env = process.env.NODE_ENV || 'development';
this.config = this.loadConfig();
}

// 加载配置
loadConfig() {
const baseConfig = {
port: process.env.PORT || 3000,
host: process.env.HOST || 'localhost',
database: {
url: process.env.DATABASE_URL || 'mongodb://localhost:27017/app',
options: {
useNewUrlParser: true,
useUnifiedTopology: true
}
},
jwt: {
secret: process.env.JWT_SECRET || 'your-secret-key',
expiresIn: process.env.JWT_EXPIRES_IN || '24h'
},
redis: {
url: process.env.REDIS_URL || 'redis://localhost:6379'
},
cors: {
origin: process.env.CORS_ORIGIN || '*',
credentials: true
}
};

// 环境特定配置
switch (this.env) {
case 'production':
return {
...baseConfig,
database: {
...baseConfig.database,
options: {
...baseConfig.database.options,
ssl: true
}
},
cors: {
origin: process.env.CORS_ORIGIN?.split(',') || [],
credentials: true
}
};

case 'test':
return {
...baseConfig,
database: {
...baseConfig.database,
url: process.env.TEST_DATABASE_URL || 'mongodb://localhost:27017/test'
}
};

default:
return baseConfig;
}
}

// 获取配置值
get(key) {
return key.split('.').reduce((obj, k) => obj?.[k], this.config);
}

// 检查是否为生产环境
isProduction() {
return this.env === 'production';
}

// 检查是否为测试环境
isTest() {
return this.env === 'test';
}
}

2. 健康检查

// 健康检查服务
class HealthCheckService {
constructor() {
this.checks = new Map();
this.startTime = Date.now();
}

// 添加健康检查
addCheck(name, checkFunction) {
this.checks.set(name, checkFunction);
}

// 执行健康检查
async performHealthCheck() {
const results = {};
const overallStatus = { healthy: true, timestamp: new Date().toISOString() };

for (const [name, checkFunction] of this.checks.entries()) {
try {
const result = await checkFunction();
results[name] = {
status: 'healthy',
details: result
};
} catch (error) {
results[name] = {
status: 'unhealthy',
error: error.message
};
overallStatus.healthy = false;
}
}

return {
status: overallStatus.healthy ? 'healthy' : 'unhealthy',
timestamp: overallStatus.timestamp,
uptime: Date.now() - this.startTime,
checks: results
};
}

// 数据库健康检查
async checkDatabase() {
try {
const db = require('../database');
await db.connection.db.admin().ping();
return { message: '数据库连接正常' };
} catch (error) {
throw new Error(`数据库连接失败: ${error.message}`);
}
}

// Redis健康检查
async checkRedis() {
try {
const redis = require('../redis');
await redis.ping();
return { message: 'Redis连接正常' };
} catch (error) {
throw new Error(`Redis连接失败: ${error.message}`);
}
}

// 外部API健康检查
async checkExternalAPI() {
try {
const response = await fetch('https://httpbin.org/status/200');
if (response.ok) {
return { message: '外部API访问正常' };
}
throw new Error(`外部API响应异常: ${response.status}`);
} catch (error) {
throw new Error(`外部API检查失败: ${error.message}`);
}
}
}

// 健康检查路由
const healthCheckRoutes = (app) => {
const healthService = new HealthCheckService();

// 添加默认检查
healthService.addCheck('database', () => healthService.checkDatabase());
healthService.addCheck('redis', () => healthService.checkRedis());
healthService.addCheck('external-api', () => healthService.checkExternalAPI());

// 健康检查端点
app.get('/health', async (req, res) => {
const health = await healthService.performHealthCheck();
const statusCode = health.status === 'healthy' ? 200 : 503;

res.status(statusCode).json(health);
});

// 简单健康检查
app.get('/health/simple', (req, res) => {
res.status(200).json({
status: 'ok',
timestamp: new Date().toISOString()
});
});
};

通过以上完整的API设计与实现方案,可以构建出高质量、安全可靠、性能优异的API接口系统。每个模块都包含了详细的实现步骤和核心代码逻辑,为开发团队提供了完整的参考指南。