5.8 KiB
5.8 KiB
API 响应格式说明
统一响应格式
所有 API 接口现在都返回统一的格式:
{
"code": 0,
"message": "Success",
"data": {}
}
字段说明
code (Number)
- 0: 成功
- 400: 请求参数错误
- 401: 未授权/Token 无效
- 403: 禁止访问
- 404: 资源不找到
- 409: 冲突(如重复数据)
- 500: 服务器内部错误
message (String)
- 操作结果的描述信息
- 成功时通常为 "Success" 或具体的成功消息
- 失败时为错误描述
data (Object | Array | null)
- 成功时包含返回的数据
- 失败时为 null
响应示例
成功响应
1. 登录成功
{
"code": 0,
"message": "Login successful",
"data": {
"user": {
"id": "uuid",
"nickname": "用户昵称",
"avatar": "https://...",
"language": "zh",
"balance": 0.00
},
"token": "Bearer eyJhbGc...",
"refreshToken": "eyJhbGc..."
}
}
2. 获取列表
{
"code": 0,
"message": "Success",
"data": {
"items": [
{ "id": 1, "name": "Item 1" },
{ "id": 2, "name": "Item 2" }
],
"pagination": {
"total": 100,
"page": 1,
"limit": 10,
"totalPages": 10
}
}
}
3. 创建资源
{
"code": 0,
"message": "Created successfully",
"data": {
"id": "uuid",
"name": "New Item",
"createdAt": "2025-12-05T12:00:00Z"
}
}
4. 删除资源
{
"code": 0,
"message": "Deleted successfully",
"data": null
}
错误响应
1. 参数验证错误 (400)
{
"code": 400,
"message": "Invalid input data",
"data": null,
"errors": [
{
"field": "email",
"message": "Email is required"
}
]
}
2. 未授权 (401)
{
"code": 401,
"message": "Invalid or expired token",
"data": null
}
3. 禁止访问 (403)
{
"code": 403,
"message": "Insufficient permissions",
"data": null
}
4. 资源不存在 (404)
{
"code": 404,
"message": "Resource not found",
"data": null
}
5. 服务器错误 (500)
{
"code": 500,
"message": "Internal server error",
"data": null
}
实现方式
方式 1: 使用响应工具函数
const { sendSuccess, sendError, sendPaginated } = require('../utils/response');
// 成功响应
sendSuccess(res, data, 'Operation successful');
// 错误响应
sendError(res, 'Error message', 400, 400);
// 分页响应
sendPaginated(res, items, total, page, limit, 'Success');
方式 2: 自动转换(推荐)
系统已配置响应格式化中间件,会自动转换所有响应:
// 旧格式(会自动转换)
res.json({
success: true,
data: { ... }
});
// 自动转换为
{
code: 0,
message: "Success",
data: { ... }
}
前端使用
判断请求是否成功
const response = await api.login(code);
// 方式 1: 判断 code
if (response.code === 0) {
// 成功
console.log(response.data);
} else {
// 失败
console.error(response.message);
}
// 方式 2: 兼容旧格式
const isSuccess = (response.code === 0) || (response.success === true);
if (isSuccess) {
// 成功
}
错误处理
try {
const response = await api.someRequest();
if (response.code !== 0) {
// 显示错误消息
uni.showToast({
title: response.message,
icon: 'none'
});
return;
}
// 处理成功数据
const data = response.data;
} catch (error) {
console.error('Request failed:', error);
}
迁移指南
从旧格式迁移
如果你的代码使用旧格式 { success: true, data: {} }:
1. 更新判断逻辑
// 旧代码
if (data.success) {
// ...
}
// 新代码
if (data.code === 0) {
// ...
}
// 或兼容两种格式
if (data.code === 0 || data.success === true) {
// ...
}
2. 更新错误处理
// 旧代码
if (!data.success) {
console.error(data.error.message);
}
// 新代码
if (data.code !== 0) {
console.error(data.message);
}
3. 更新数据访问
// 数据访问方式不变
const user = data.data.user;
const items = data.data.items;
注意事项
- code 为 0 表示成功,其他值表示失败
- message 字段始终存在,包含操作结果描述
- data 字段在失败时为 null
- 开发环境下,错误响应可能包含额外的 error 字段用于调试
- HTTP 状态码与 code 字段可能不同,建议以 code 字段为准
相关文件
backend/src/middleware/responseFormatter.js- 响应格式化中间件backend/src/utils/response.js- 响应工具函数backend/src/middleware/errorHandler.js- 错误处理中间件
测试
测试成功响应
curl http://localhost:3000/api/v1/categories
# 期望输出
{
"code": 0,
"message": "Success",
"data": [...]
}
测试错误响应
curl http://localhost:3000/api/v1/services/invalid-id
# 期望输出
{
"code": 404,
"message": "Service not found",
"data": null
}
常见问题
Q: 为什么要统一响应格式?
A: 统一的响应格式让前端更容易处理 API 响应,减少判断逻辑,提高代码可维护性。
Q: code 和 HTTP 状态码有什么区别?
A: HTTP 状态码是传输层的状态,code 是业务层的状态。建议前端主要使用 code 判断业务成功与否。
Q: 如何处理分页数据?
A: 分页数据包含在 data 对象中,包括 items 数组和 pagination 对象。
Q: 旧代码会自动转换吗?
A: 是的,响应格式化中间件会自动转换旧格式到新格式,无需修改现有控制器代码。
Q: 如何在开发环境查看详细错误?
A: 开发环境下,错误响应会包含额外的 error 对象,包含详细的错误信息和堆栈跟踪。