✅ 健康检查功能: - 实现完整的健康检查接口(/api/health, /api/health/detailed) - 支持MySQL和Redis依赖状态检查 - 包含系统信息、性能指标监控 - 修复this上下文问题,确保服务方法正常调用 - 添加全面的健康检查测试用例 📝 Swagger文档优化: - 创建全局响应Schema定义和错误码说明 - 完善API文档,包含详细的错误码表格 - 添加JWT认证说明和响应格式示例 - 增加全局组件、响应模板和示例 - 创建Swagger文档功能测试 🎯 任务完成: - ✅ 5.0 健康检查接口 - 实现系统和依赖健康状态监控 - ✅ 7.0 Swagger文档完善 - 增加全局响应示例和错误码说明 📁 新增文件: - src/controllers/health.controller.ts - 健康检查控制器 - src/services/health.service.ts - 健康检查服务层 - src/type/health.type.ts - 健康检查类型定义 - src/validators/health.response.ts - 健康检查响应验证 - src/validators/global.response.ts - 全局响应Schema定义 - src/tests/health.test.ts - 健康检查功能测试 - src/tests/redis.test.ts - Redis连接测试 - src/tests/swagger.test.ts - Swagger文档功能测试
15 KiB
15 KiB
HTTP 状态码完整指南
概述
HTTP 状态码是服务器响应客户端请求时返回的三位数字代码,用于表示请求的处理结果。本文档详细列举了所有常见的HTTP状态码,以及在API开发中的最佳实践。
状态码分类
- 1xx (信息性): 请求已接收,继续处理
- 2xx (成功): 请求已成功被服务器接收、理解、并接受
- 3xx (重定向): 需要后续操作才能完成这一请求
- 4xx (客户端错误): 请求包含错误语法或无法被执行
- 5xx (服务器错误): 服务器无法完成明显有效的请求
1xx 信息性状态码
100 Continue
- 说明: 继续,客户端应继续其请求
- 使用场景: 大文件上传时的初始确认
- 处理建议: 通常由HTTP库自动处理,开发者无需特殊处理
101 Switching Protocols
- 说明: 切换协议,服务器根据客户端的请求切换协议
- 使用场景: WebSocket握手、HTTP升级到HTTPS
- 处理建议: 确保客户端支持新协议
102 Processing
- 说明: 处理中,服务器已接收并正在处理请求
- 使用场景: 长时间运行的请求
- 处理建议: 告知客户端请求正在处理,避免超时
2xx 成功状态码
200 OK
- 说明: 请求成功
- 使用场景: GET、PUT、PATCH请求成功
- 返回内容: 请求的资源或操作结果
- 示例响应:
{
"code": 0,
"message": "操作成功",
"data": { "id": 1, "name": "用户" }
}
201 Created
- 说明: 创建成功
- 使用场景: POST请求成功创建资源
- 返回内容: 新创建的资源信息
- Header建议: 添加
Location
头指向新资源 - 示例响应:
{
"code": 0,
"message": "创建成功",
"data": { "id": 123, "name": "新用户" }
}
202 Accepted
- 说明: 已接受,请求已被接受,但尚未处理完成
- 使用场景: 异步任务、批量操作
- 返回内容: 任务状态或追踪信息
- 示例响应:
{
"code": 0,
"message": "任务已提交",
"data": { "taskId": "task-123", "status": "processing" }
}
204 No Content
- 说明: 无内容,请求成功但无返回内容
- 使用场景: DELETE请求成功、PUT更新成功
- 返回内容: 空响应体
- 注意: 不应返回JSON响应体
206 Partial Content
- 说明: 部分内容
- 使用场景: 文件断点续传、大文件分块下载
- Header要求: 必须包含
Content-Range
- 处理建议: 实现Range请求支持
3xx 重定向状态码
301 Moved Permanently
- 说明: 永久重定向
- 使用场景: URL结构永久性改变、API版本升级
- Header要求: 必须包含
Location
头 - SEO影响: 搜索引擎会更新索引
302 Found
- 说明: 临时重定向
- 使用场景: 临时维护、负载均衡
- Header要求: 必须包含
Location
头 - 注意: 不会影响搜索引擎索引
304 Not Modified
- 说明: 未修改,资源未发生变化
- 使用场景: 缓存验证、条件请求
- Header要求: 配合
ETag
或Last-Modified
- 性能优化: 减少带宽消耗
307 Temporary Redirect
- 说明: 临时重定向(保持请求方法)
- 使用场景: 确保POST/PUT等方法不被改变
- 与302区别: 严格保持原始HTTP方法
308 Permanent Redirect
- 说明: 永久重定向(保持请求方法)
- 使用场景: API端点永久迁移,需保持HTTP方法
- 与301区别: 严格保持原始HTTP方法
4xx 客户端错误状态码
400 Bad Request
- 说明: 请求语法错误或参数无效
- 常见原因:
- JSON格式错误
- 必需参数缺失
- 参数类型不正确
- 参数值超出范围
- 解决方法:
- 验证请求格式
- 检查参数完整性
- 使用参数验证库
- 示例响应:
{
"code": 400,
"message": "参数校验失败",
"data": null,
"errors": [
{ "field": "email", "message": "邮箱格式不正确" },
{ "field": "age", "message": "年龄必须大于0" }
]
}
401 Unauthorized
- 说明: 未认证,需要身份验证
- 常见原因:
- 缺少认证信息
- Token已过期
- Token格式错误
- 认证信息无效
- 解决方法:
- 提供有效的认证信息
- 刷新过期的Token
- 重新登录
- Header建议: 添加
WWW-Authenticate
头 - 示例响应:
{
"code": 401,
"message": "认证失败,请重新登录",
"data": null
}
403 Forbidden
- 说明: 禁止访问,已认证但无权限
- 常见原因:
- 权限不足
- 资源被禁止访问
- IP被封禁
- 账户被冻结
- 解决方法:
- 联系管理员获取权限
- 检查用户角色设置
- 验证访问策略
- 示例响应:
{
"code": 403,
"message": "权限不足,无法访问该资源",
"data": null
}
404 Not Found
- 说明: 资源不存在
- 常见原因:
- URL路径错误
- 资源已被删除
- 资源ID不存在
- API端点不存在
- 解决方法:
- 检查URL拼写
- 验证资源是否存在
- 确认API版本
- 示例响应:
{
"code": 404,
"message": "请求的资源不存在",
"data": null
}
405 Method Not Allowed
- 说明: 请求方法不被允许
- 常见原因:
- 使用了不支持的HTTP方法
- GET请求用于需要POST的接口
- Header要求: 必须包含
Allow
头列出支持的方法 - 示例响应:
{
"code": 405,
"message": "不支持的请求方法",
"data": null,
"allowedMethods": ["GET", "POST"]
}
406 Not Acceptable
- 说明: 不可接受,服务器无法返回客户端可接受的内容格式
- 常见原因:
- Accept头指定了不支持的格式
- 内容协商失败
- 解决方法: 调整Accept头或支持更多格式
409 Conflict
- 说明: 冲突,请求与当前资源状态冲突
- 常见原因:
- 资源已存在
- 并发修改冲突
- 业务逻辑冲突
- 解决方法:
- 重新获取最新状态
- 解决冲突后重试
- 示例响应:
{
"code": 409,
"message": "用户名已存在",
"data": null
}
410 Gone
- 说明: 资源已永久删除
- 使用场景: 资源被主动删除且不会恢复
- 与404区别: 明确表示资源曾经存在但已删除
411 Length Required
- 说明: 需要Content-Length头
- 常见原因: POST/PUT请求缺少Content-Length
- 解决方法: 添加Content-Length头
412 Precondition Failed
- 说明: 前置条件失败
- 使用场景: 条件请求(If-Match、If-None-Match等)失败
- 常见原因: ETag不匹配、条件不满足
413 Payload Too Large
- 说明: 请求体过大
- 常见原因:
- 上传文件超出限制
- JSON数据过大
- 解决方法:
- 减小文件大小
- 分块上传
- 调整服务器限制
- 示例响应:
{
"code": 413,
"message": "上传文件大小超出限制(最大10MB)",
"data": null
}
414 URI Too Long
- 说明: URI过长
- 常见原因: GET请求参数过多
- 解决方法: 使用POST请求或减少参数
415 Unsupported Media Type
- 说明: 不支持的媒体类型
- 常见原因:
- Content-Type不正确
- 上传了不支持的文件格式
- 解决方法: 检查Content-Type头
- 示例响应:
{
"code": 415,
"message": "不支持的文件格式,仅支持图片文件",
"data": null,
"supportedTypes": ["image/jpeg", "image/png", "image/gif"]
}
422 Unprocessable Entity
- 说明: 无法处理的实体,语法正确但语义错误
- 常见原因:
- 业务逻辑验证失败
- 数据关联性错误
- 状态不允许操作
- 与400区别: 语法正确但业务逻辑错误
- 示例响应:
{
"code": 422,
"message": "业务逻辑验证失败",
"data": null,
"errors": [{ "field": "endDate", "message": "结束日期不能早于开始日期" }]
}
423 Locked
- 说明: 资源被锁定
- 使用场景: WebDAV、文件编辑锁定
- 解决方法: 等待锁定释放或强制解锁
429 Too Many Requests
- 说明: 请求过于频繁
- 常见原因:
- 超出API调用频率限制
- 防暴力破解保护
- Header建议:
Retry-After
: 建议重试时间X-RateLimit-*
: 频率限制信息
- 解决方法:
- 降低请求频率
- 实现指数退避重试
- 示例响应:
{
"code": 429,
"message": "请求过于频繁,请稍后重试",
"data": null,
"retryAfter": 60
}
5xx 服务器错误状态码
500 Internal Server Error
- 说明: 服务器内部错误
- 常见原因:
- 代码异常未捕获
- 数据库连接失败
- 第三方服务异常
- 配置错误
- 解决方法:
- 检查服务器日志
- 修复代码bug
- 验证配置正确性
- 开发环境响应:
{
"code": 500,
"message": "服务器内部错误",
"data": null,
"traceId": "req-123456",
"details": "NullPointerException at line 42",
"stack": "详细堆栈信息..."
}
- 生产环境响应:
{
"code": 500,
"message": "服务器内部错误,请稍后重试",
"data": null,
"traceId": "req-123456"
}
501 Not Implemented
- 说明: 功能未实现
- 使用场景: API端点规划但未开发
- 解决方法: 等待功能开发完成
502 Bad Gateway
- 说明: 网关错误
- 常见原因:
- 上游服务器响应无效
- 代理服务器配置错误
- 负载均衡器问题
- 解决方法:
- 检查上游服务状态
- 验证代理配置
- 重启相关服务
503 Service Unavailable
- 说明: 服务不可用
- 常见原因:
- 服务器维护
- 系统过载
- 依赖服务不可用
- Header建议: 添加
Retry-After
头 - 解决方法:
- 等待维护完成
- 扩容服务器
- 修复依赖服务
- 示例响应:
{
"code": 503,
"message": "服务暂时不可用,系统维护中",
"data": null,
"retryAfter": 3600
}
504 Gateway Timeout
- 说明: 网关超时
- 常见原因:
- 上游服务响应超时
- 网络延迟过高
- 处理时间过长
- 解决方法:
- 优化上游服务性能
- 增加超时时间
- 实现异步处理
505 HTTP Version Not Supported
- 说明: HTTP版本不支持
- 解决方法: 使用支持的HTTP版本
API 错误处理最佳实践
1. 统一错误响应格式
{
"code": 400,
"message": "用户友好的错误描述",
"data": null,
"traceId": "req-uuid-123",
"timestamp": "2024-01-01T12:00:00Z",
"errors": [
{
"field": "email",
"message": "邮箱格式不正确",
"code": "INVALID_EMAIL_FORMAT"
}
]
}
2. 错误码设计原则
- HTTP状态码: 表示HTTP层面的处理结果
- 业务错误码: 表示具体的业务错误类型
- 错误消息: 提供用户友好的错误描述
- 错误详情: 开发环境提供详细信息,生产环境保护敏感信息
3. 常见业务错误码映射
业务场景 | HTTP状态码 | 业务错误码 | 错误消息 |
---|---|---|---|
参数校验失败 | 400 | 1001 | 参数校验失败 |
用户名或密码错误 | 400 | 1002 | 用户名或密码错误 |
Token无效 | 401 | 1003 | 认证失败,请重新登录 |
权限不足 | 403 | 1004 | 权限不足 |
资源不存在 | 404 | 1005 | 请求的资源不存在 |
资源已存在 | 409 | 1006 | 资源已存在 |
请求频率限制 | 429 | 1007 | 请求过于频繁 |
系统错误 | 500 | 2001 | 系统内部错误 |
数据库错误 | 500 | 2002 | 数据存储错误 |
第三方服务错误 | 502 | 2003 | 外部服务错误 |
4. 错误日志记录
// 错误日志应包含的信息
{
timestamp: "2024-01-01T12:00:00Z",
level: "ERROR",
message: "用户登录失败",
traceId: "req-uuid-123",
userId: "user-456",
ip: "192.168.1.100",
userAgent: "Mozilla/5.0...",
path: "/api/login",
method: "POST",
statusCode: 400,
errorCode: 1002,
errorType: "BUSINESS_ERROR",
stack: "错误堆栈信息...",
requestBody: { /* 脱敏后的请求数据 */ },
context: { /* 其他上下文信息 */ }
}
5. 客户端错误处理建议
// 客户端错误处理示例
async function handleApiError(error: ApiError) {
const { status, data } = error.response;
switch (status) {
case 400:
// 显示参数错误信息
showValidationErrors(data.errors);
break;
case 401:
// 清除本地token,跳转登录页
clearToken();
redirectToLogin();
break;
case 403:
// 显示权限不足提示
showPermissionDenied();
break;
case 404:
// 显示资源不存在
showNotFound();
break;
case 429:
// 实现指数退避重试
await retryWithBackoff();
break;
case 500:
case 502:
case 503:
case 504:
// 显示系统错误,建议稍后重试
showSystemError(data.message);
break;
default:
// 显示通用错误信息
showGenericError();
}
}
6. 监控和告警
- 4xx错误: 监控客户端错误趋势,可能表示API设计问题
- 5xx错误: 立即告警,表示系统问题需要紧急处理
- 特定错误码: 针对业务关键错误设置专门监控
- 错误率阈值: 设置错误率阈值告警
总结
正确使用HTTP状态码是RESTful API设计的重要组成部分。遵循标准的状态码使用规范,结合清晰的错误消息和完善的错误处理机制,能够显著提升API的可用性和开发体验。
关键原则
- 语义明确: 状态码应准确反映请求的处理结果
- 一致性: 相同类型的错误应使用相同的状态码
- 用户友好: 错误消息应易于理解且可操作
- 安全性: 生产环境不暴露敏感系统信息
- 可追踪: 每个错误都应有唯一标识便于追踪
- 可监控: 重要错误应有相应的监控和告警机制
正确实施这些错误处理策略将大大提升系统的健壮性和可维护性。