Files
app-api/.qoder/repowiki/zh/content/核心模块/统一响应.md
T
2026-05-27 18:07:55 +08:00

366 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 统一响应
<cite>
**本文引用的文件**
- [internal/response/response.go](file://internal/response/response.go)
- [internal/handler/health.go](file://internal/handler/health.go)
- [internal/handler/brand.go](file://internal/handler/brand.go)
- [internal/handler/model.go](file://internal/handler/model.go)
- [internal/router/router.go](file://internal/router/router.go)
- [internal/middleware/logger.go](file://internal/middleware/logger.go)
- [internal/middleware/request_id.go](file://internal/middleware/request_id.go)
- [internal/middleware/cors.go](file://internal/middleware/cors.go)
- [pkg/encode/base64.go](file://pkg/encode/base64.go)
- [pkg/logger/logger.go](file://pkg/logger/logger.go)
- [cmd/server/main.go](file://cmd/server/main.go)
- [README.md](file://README.md)
</cite>
## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [详细组件分析](#详细组件分析)
6. [依赖分析](#依赖分析)
7. [性能考虑](#性能考虑)
8. [故障排查指南](#故障排查指南)
9. [结论](#结论)
10. [附录](#附录)
## 简介
本文件系统化阐述 Luxsin 应用 API 的“统一响应”模块,围绕响应格式设计原则、实现机制与使用规范展开,覆盖响应结构、状态码策略、错误处理、国际化与调试信息、扩展与自定义选项、性能优化与最佳实践。目标是帮助初学者快速理解统一响应在 API 设计中的一致性价值,同时为高级开发者提供实现细节与扩展路径。
## 项目结构
统一响应模块位于 internal/response,配合各 handler 在业务层统一输出 JSON 结构;路由与中间件负责请求生命周期管理与日志记录;编码工具提供可选的 Base64 响应能力;日志与服务器入口负责运行时配置与生命周期控制。
```mermaid
graph TB
subgraph "应用入口"
MAIN["cmd/server/main.go"]
end
subgraph "HTTP 层"
ROUTER["internal/router/router.go"]
M_REQID["internal/middleware/request_id.go"]
M_LOG["internal/middleware/logger.go"]
M_CORS["internal/middleware/cors.go"]
end
subgraph "业务层"
HANDLER_HEALTH["internal/handler/health.go"]
HANDLER_BRAND["internal/handler/brand.go"]
HANDLER_MODEL["internal/handler/model.go"]
end
subgraph "通用能力"
RESP["internal/response/response.go"]
ENCODE["pkg/encode/base64.go"]
LOGPKG["pkg/logger/logger.go"]
end
MAIN --> ROUTER
ROUTER --> M_REQID
ROUTER --> M_LOG
ROUTER --> M_CORS
ROUTER --> HANDLER_HEALTH
ROUTER --> HANDLER_BRAND
ROUTER --> HANDLER_MODEL
HANDLER_HEALTH --> RESP
HANDLER_BRAND --> RESP
HANDLER_MODEL --> RESP
HANDLER_BRAND --> ENCODE
HANDLER_MODEL --> ENCODE
MAIN --> LOGPKG
```
图表来源
- [cmd/server/main.go:22-96](file://cmd/server/main.go#L22-L96)
- [internal/router/router.go:14-42](file://internal/router/router.go#L14-L42)
- [internal/middleware/request_id.go:20-31](file://internal/middleware/request_id.go#L20-L31)
- [internal/middleware/logger.go:10-46](file://internal/middleware/logger.go#L10-L46)
- [internal/middleware/cors.go:7-21](file://internal/middleware/cors.go#L7-L21)
- [internal/handler/health.go:14-19](file://internal/handler/health.go#L14-L19)
- [internal/handler/brand.go:26-50](file://internal/handler/brand.go#L26-L50)
- [internal/handler/model.go:26-51](file://internal/handler/model.go#L26-L51)
- [internal/response/response.go:9-37](file://internal/response/response.go#L9-L37)
- [pkg/encode/base64.go:44-52](file://pkg/encode/base64.go#L44-L52)
- [pkg/logger/logger.go:8-20](file://pkg/logger/logger.go#L8-L20)
章节来源
- [README.md:1-123](file://README.md#L1-L123)
- [cmd/server/main.go:22-96](file://cmd/server/main.go#L22-L96)
- [internal/router/router.go:14-42](file://internal/router/router.go#L14-L42)
## 核心组件
- 统一响应体结构
- 字段:code、message、data(可选)
- 语义:code 为业务/协议态码;message 为人类可读消息;data 承载具体业务数据
- 响应函数族
- OK:成功响应,code=0message="ok"
- Fail:通用失败响应,传入 HTTP 状态码、业务态码与消息
- BadRequest:快捷失败,HTTP 400,业务态码 40000
- InternalError:快捷失败,HTTP 500,业务态码 50000
这些函数统一封装了 JSON 输出,确保所有 handler 以一致的结构返回,便于客户端解析与前端统一处理。
章节来源
- [internal/response/response.go:9-37](file://internal/response/response.go#L9-L37)
## 架构总览
统一响应贯穿“路由 -> 中间件 -> 处理器 -> 统一响应”的调用链路。中间件负责请求标识、跨域与日志;处理器完成参数解析、业务执行与错误处理;统一响应模块负责最终的 JSON 输出。
```mermaid
sequenceDiagram
participant C as "客户端"
participant R as "路由/中间件"
participant H as "处理器"
participant S as "统一响应"
C->>R : "HTTP 请求"
R->>R : "请求ID/日志/CORS"
R->>H : "进入处理器"
H->>H : "参数解析/业务执行"
alt "成功"
H->>S : "OK(data)"
S-->>C : "{code,message,data}"
else "失败"
H->>S : "Fail/400/500(...)"
S-->>C : "{code,message}"
end
```
图表来源
- [internal/router/router.go:14-42](file://internal/router/router.go#L14-L42)
- [internal/middleware/request_id.go:20-31](file://internal/middleware/request_id.go#L20-L31)
- [internal/middleware/logger.go:10-46](file://internal/middleware/logger.go#L10-L46)
- [internal/middleware/cors.go:7-21](file://internal/middleware/cors.go#L7-L21)
- [internal/handler/health.go:14-19](file://internal/handler/health.go#L14-L19)
- [internal/response/response.go:15-37](file://internal/response/response.go#L15-L37)
## 详细组件分析
### 统一响应模块(internal/response
- 设计要点
- 结构体 Body 仅包含三字段,简洁明确,避免冗余
- OK/Fail/BadRequest/InternalError 一组函数覆盖常见场景
- 通过 gin.Context 输出 JSON,保持与框架一致的 Content-Type 与状态码
- 数据流
- 输入:gin.Context、业务数据或错误信息
- 输出:标准化 JSON 响应
- 错误处理策略
- 成功路径:OK(data)
- 失败路径:Fail(HTTP状态, 业务态码, 消息),或快捷 BadRequest/InternalError
- 可扩展性
- 可新增更多快捷函数(如 Unauthorized、NotFound 等)
- 可引入国际化消息映射,按语言返回 message
```mermaid
classDiagram
class Body {
+int code
+string message
+any data
}
class ResponseAPI {
+OK(c, data)
+Fail(c, httpStatus, code, message)
+BadRequest(c, message)
+InternalError(c, message)
}
ResponseAPI --> Body : "构造并输出"
```
图表来源
- [internal/response/response.go:9-37](file://internal/response/response.go#L9-L37)
章节来源
- [internal/response/response.go:9-37](file://internal/response/response.go#L9-L37)
### 处理器与统一响应的协作
- 健康检查处理器
- 使用 OK 返回简单健康状态
- 品牌与型号处理器
- 从仓库层获取数据,发生错误时统一调用 InternalError
- 支持可选的 Base64 响应(通过参数 base64Resp 控制),内部先 JSON 编码再自定义 Base64 转换
```mermaid
sequenceDiagram
participant C as "客户端"
participant H as "品牌/型号处理器"
participant Repo as "仓库层"
participant Resp as "统一响应"
C->>H : "GET /audio/getBrand?base64Resp=true"
H->>Repo : "List(...)"
Repo-->>H : "数据或错误"
alt "错误"
H->>Resp : "InternalError(...)"
Resp-->>C : "{code,message}"
else "成功"
H->>H : "按需JSON/Base64编码"
H-->>C : "JSON或Base64字符串"
end
```
图表来源
- [internal/handler/brand.go:26-50](file://internal/handler/brand.go#L26-L50)
- [internal/handler/model.go:26-51](file://internal/handler/model.go#L26-L51)
- [pkg/encode/base64.go:35-52](file://pkg/encode/base64.go#L35-L52)
- [internal/response/response.go:34-37](file://internal/response/response.go#L34-L37)
章节来源
- [internal/handler/health.go:14-19](file://internal/handler/health.go#L14-L19)
- [internal/handler/brand.go:26-50](file://internal/handler/brand.go#L26-L50)
- [internal/handler/model.go:26-51](file://internal/handler/model.go#L26-L51)
- [pkg/encode/base64.go:35-52](file://pkg/encode/base64.go#L35-L52)
### 中间件与日志
- 请求 ID 中间件
- 自动生成或透传 X-Request-ID,便于全链路追踪
- 日志中间件
- 记录状态码、方法、路径、耗时、IP、请求 ID、错误等
- 按状态码分级(info/warn/error)输出
- CORS 中间件
- 设置允许的源、方法、头,并暴露 X-Request-ID
```mermaid
flowchart TD
Start(["进入中间件链"]) --> ReqID["生成/透传请求ID"]
ReqID --> Logger["记录请求开始"]
Logger --> Next["继续下一个处理器"]
Next --> Status{"状态码>=500?"}
Status --> |是| LogErr["记录错误日志"]
Status --> |否| Status400{"状态码>=400?"}
Status400 --> |是| LogWarn["记录告警日志"]
Status400 --> |否| LogInfo["记录正常日志"]
LogErr --> End(["结束"])
LogWarn --> End
LogInfo --> End
```
图表来源
- [internal/middleware/request_id.go:20-31](file://internal/middleware/request_id.go#L20-L31)
- [internal/middleware/logger.go:10-46](file://internal/middleware/logger.go#L10-L46)
- [internal/middleware/cors.go:7-21](file://internal/middleware/cors.go#L7-L21)
章节来源
- [internal/middleware/request_id.go:20-31](file://internal/middleware/request_id.go#L20-L31)
- [internal/middleware/logger.go:10-46](file://internal/middleware/logger.go#L10-L46)
- [internal/middleware/cors.go:7-21](file://internal/middleware/cors.go#L7-L21)
### 编码与响应格式扩展
- Base64 响应
- 通过参数 base64Resp 控制是否返回自定义 Base64 编码的 JSON
- 内部先 JSON 编码,再使用自定义字符映射表进行 Base64 转换
- 与统一响应的结合
- 当启用 Base64 时,处理器直接输出字符串,不走统一响应的 JSON 结构
- 当未启用时,统一响应负责输出标准 JSON 结构
章节来源
- [pkg/encode/base64.go:44-52](file://pkg/encode/base64.go#L44-L52)
- [internal/handler/brand.go:37-47](file://internal/handler/brand.go#L37-L47)
- [internal/handler/model.go:38-48](file://internal/handler/model.go#L38-L48)
## 依赖分析
- 统一响应依赖 Gin 上下文输出 JSON
- 处理器依赖统一响应与仓库/服务层
- 中间件依赖 Gin 与日志库
- 编码工具独立于响应模块,但被处理器条件使用
```mermaid
graph LR
Gin["github.com/gin-gonic/gin"] --> RESP["internal/response/response.go"]
RESP --> HANDLER_HEALTH["internal/handler/health.go"]
RESP --> HANDLER_BRAND["internal/handler/brand.go"]
RESP --> HANDLER_MODEL["internal/handler/model.go"]
HANDLER_BRAND --> ENCODE["pkg/encode/base64.go"]
HANDLER_MODEL --> ENCODE
ROUTER["internal/router/router.go"] --> M_REQID["internal/middleware/request_id.go"]
ROUTER --> M_LOG["internal/middleware/logger.go"]
ROUTER --> M_CORS["internal/middleware/cors.go"]
MAIN["cmd/server/main.go"] --> LOGPKG["pkg/logger/logger.go"]
```
图表来源
- [internal/response/response.go:3-7](file://internal/response/response.go#L3-L7)
- [internal/handler/health.go:4-6](file://internal/handler/health.go#L4-L6)
- [internal/handler/brand.go:7-11](file://internal/handler/brand.go#L7-L11)
- [internal/handler/model.go:7-12](file://internal/handler/model.go#L7-L12)
- [pkg/encode/base64.go:3-6](file://pkg/encode/base64.go#L3-L6)
- [internal/router/router.go:3-12](file://internal/router/router.go#L3-L12)
- [internal/middleware/request_id.go:7](file://internal/middleware/request_id.go#L7)
- [internal/middleware/logger.go:6-8](file://internal/middleware/logger.go#L6-L8)
- [internal/middleware/cors.go:4](file://internal/middleware/cors.go#L4)
- [cmd/server/main.go:12-19](file://cmd/server/main.go#L12-L19)
- [pkg/logger/logger.go:3-5](file://pkg/logger/logger.go#L3-L5)
章节来源
- [internal/response/response.go:3-7](file://internal/response/response.go#L3-L7)
- [internal/handler/brand.go:7-11](file://internal/handler/brand.go#L7-L11)
- [internal/handler/model.go:7-12](file://internal/handler/model.go#L7-L12)
- [pkg/encode/base64.go:3-6](file://pkg/encode/base64.go#L3-L6)
- [internal/router/router.go:3-12](file://internal/router/router.go#L3-L12)
- [internal/middleware/request_id.go:7](file://internal/middleware/request_id.go#L7)
- [internal/middleware/logger.go:6-8](file://internal/middleware/logger.go#L6-L8)
- [internal/middleware/cors.go:4](file://internal/middleware/cors.go#L4)
- [cmd/server/main.go:12-19](file://cmd/server/main.go#L12-L19)
- [pkg/logger/logger.go:3-5](file://pkg/logger/logger.go#L3-L5)
## 性能考虑
- 统一响应本身开销极低,主要成本在序列化与网络传输
- 对大对象响应,优先评估是否需要 Base64 压缩,注意额外的编码/解码成本
- 使用中间件的日志分级与请求 ID,有助于定位慢请求与异常点
- 生产环境建议开启 Gin Release 模式与合适的日志级别
## 故障排查指南
- 常见问题
- 业务错误未统一返回:检查处理器是否调用统一响应函数
- Base64 响应异常:确认参数 base64Resp 的取值与编码流程
- 日志缺失:确认中间件顺序与日志中间件是否正确设置
- 排查步骤
- 通过请求 ID 在日志中检索整条链路
- 关注状态码分级日志,定位 4xx/5xx 场景
- 若出现内部错误,统一响应会返回固定业务态码,便于前端/监控识别
章节来源
- [internal/middleware/logger.go:10-46](file://internal/middleware/logger.go#L10-L46)
- [internal/middleware/request_id.go:20-31](file://internal/middleware/request_id.go#L20-L31)
- [internal/response/response.go:34-37](file://internal/response/response.go#L34-L37)
## 结论
统一响应模块通过简洁一致的 JSON 结构与函数族,显著提升了 API 的可读性、可维护性与可观测性。配合中间件与日志体系,能够快速定位问题并保障用户体验。对于国际化与调试信息,建议在现有基础上扩展消息映射与上下文元数据,进一步增强一致性与可诊断性。
## 附录
### 响应结构与状态码定义
- 响应体字段
- code:业务/协议态码(成功通常为 0,失败为正整数)
- message:人类可读消息
- data:业务数据(可选)
- 常用状态码策略
- 成功:HTTP 200 + code=0
- 客户端错误:HTTP 400 + 业务态码 40000
- 服务器错误:HTTP 500 + 业务态码 50000
- 国际化与调试
- message 可按语言映射,data 可附加 traceId/requestId 等调试信息
- Base64 响应
- 通过参数 base64Resp 控制;启用后返回自定义 Base64 编码的 JSON 字符串
章节来源
- [internal/response/response.go:9-37](file://internal/response/response.go#L9-L37)
- [pkg/encode/base64.go:44-52](file://pkg/encode/base64.go#L44-L52)
### 使用示例(路径指引)
- 健康检查
- 路径:[internal/handler/health.go:14-19](file://internal/handler/health.go#L14-L19)
- 统一响应调用:[internal/response/response.go:15-21](file://internal/response/response.go#L15-L21)
- 获取品牌列表(含 Base64 选项)
- 路径:[internal/handler/brand.go:26-50](file://internal/handler/brand.go#L26-L50)
- 统一响应调用:[internal/response/response.go:23-28](file://internal/response/response.go#L23-L28)
- 编码逻辑:[pkg/encode/base64.go:35-52](file://pkg/encode/base64.go#L35-L52)
- 获取型号列表(含 Base64 选项)
- 路径:[internal/handler/model.go:26-51](file://internal/handler/model.go#L26-L51)
- 统一响应调用:[internal/response/response.go:23-28](file://internal/response/response.go#L23-L28)
- 编码逻辑:[pkg/encode/base64.go:35-52](file://pkg/encode/base64.go#L35-L52)
### 最佳实践
- 所有处理器统一使用统一响应函数输出
- 错误路径必须记录日志并返回统一响应
- 对大对象优先评估是否需要 Base64 响应
- 生产环境启用 Release 模式与合适的日志级别
- 通过中间件保证请求 ID 与跨域配置一致生效