437 lines
15 KiB
Markdown
437 lines
15 KiB
Markdown
# 路由系统
|
||
|
||
<cite>
|
||
**本文引用的文件**
|
||
- [router.go](file://internal/router/router.go)
|
||
- [main.go](file://cmd/server/main.go)
|
||
- [cors.go](file://internal/middleware/cors.go)
|
||
- [logger.go](file://internal/middleware/logger.go)
|
||
- [request_id.go](file://internal/middleware/request_id.go)
|
||
- [health.go](file://internal/handler/health.go)
|
||
- [brand.go](file://internal/handler/brand.go)
|
||
- [model.go](file://internal/handler/model.go)
|
||
- [model_list.go](file://internal/handler/model_list.go)
|
||
- [device.go](file://internal/handler/device.go)
|
||
- [response.go](file://internal/response/response.go)
|
||
- [config.go](file://internal/config/config.go)
|
||
- [base64.go](file://pkg/encode/base64.go)
|
||
- [README.md](file://README.md)
|
||
</cite>
|
||
|
||
## 目录
|
||
1. [简介](#简介)
|
||
2. [项目结构](#项目结构)
|
||
3. [核心组件](#核心组件)
|
||
4. [架构总览](#架构总览)
|
||
5. [详细组件分析](#详细组件分析)
|
||
6. [依赖关系分析](#依赖关系分析)
|
||
7. [性能考量](#性能考量)
|
||
8. [故障排查指南](#故障排查指南)
|
||
9. [结论](#结论)
|
||
10. [附录](#附录)
|
||
|
||
## 简介
|
||
本文件系统性梳理 Luxsin 应用 API 的路由体系与中间件机制,重点覆盖:
|
||
- Gin 路由工厂函数 New 的实现与控制流
|
||
- 路由分组策略(/api/v1 与 /audio)
|
||
- 中间件执行顺序与职责(CORS、日志、请求 ID)
|
||
- 各端点功能、参数与返回规范
|
||
- 最佳实践与性能优化建议
|
||
- 典型调用序列与中间件链路分析
|
||
|
||
## 项目结构
|
||
路由系统位于 internal/router,入口在 cmd/server/main.go,配合中间件、处理器、统一响应体与配置模块协同工作。
|
||
|
||
```mermaid
|
||
graph TB
|
||
subgraph "服务入口"
|
||
MAIN["cmd/server/main.go<br/>启动 HTTP 服务器"]
|
||
end
|
||
subgraph "路由与中间件"
|
||
ROUTER["internal/router/router.go<br/>路由工厂与分组注册"]
|
||
CORS["internal/middleware/cors.go<br/>CORS 中间件"]
|
||
LOGMW["internal/middleware/logger.go<br/>日志中间件"]
|
||
REQID["internal/middleware/request_id.go<br/>请求 ID 中间件"]
|
||
end
|
||
subgraph "处理器层"
|
||
HEALTH["internal/handler/health.go"]
|
||
BRAND["internal/handler/brand.go"]
|
||
MODEL["internal/handler/model.go"]
|
||
MODELLIST["internal/handler/model_list.go"]
|
||
DEVICE["internal/handler/device.go"]
|
||
end
|
||
subgraph "基础设施"
|
||
RESP["internal/response/response.go<br/>统一响应体"]
|
||
ENCODE["pkg/encode/base64.go<br/>Base64 编解码"]
|
||
CONFIG["internal/config/config.go<br/>配置加载"]
|
||
end
|
||
MAIN --> ROUTER
|
||
ROUTER --> CORS
|
||
ROUTER --> LOGMW
|
||
ROUTER --> REQID
|
||
ROUTER --> HEALTH
|
||
ROUTER --> BRAND
|
||
ROUTER --> MODEL
|
||
ROUTER --> MODELLIST
|
||
ROUTER --> DEVICE
|
||
BRAND --> RESP
|
||
MODEL --> RESP
|
||
MODELLIST --> RESP
|
||
DEVICE --> RESP
|
||
MODELLIST --> ENCODE
|
||
BRAND --> ENCODE
|
||
MODEL --> ENCODE
|
||
```
|
||
|
||
图表来源
|
||
- [router.go:14-41](file://internal/router/router.go#L14-L41)
|
||
- [main.go:64-69](file://cmd/server/main.go#L64-L69)
|
||
- [cors.go:7-19](file://internal/middleware/cors.go#L7-L19)
|
||
- [logger.go:10-44](file://internal/middleware/logger.go#L10-L44)
|
||
- [request_id.go:20-29](file://internal/middleware/request_id.go#L20-L29)
|
||
- [health.go:14-18](file://internal/handler/health.go#L14-L18)
|
||
- [brand.go:26-49](file://internal/handler/brand.go#L26-L49)
|
||
- [model.go:26-49](file://internal/handler/model.go#L26-L49)
|
||
- [model_list.go:26-55](file://internal/handler/model_list.go#L26-L55)
|
||
- [device.go:26-84](file://internal/handler/device.go#L26-L84)
|
||
- [response.go:15-36](file://internal/response/response.go#L15-L36)
|
||
- [base64.go:44-51](file://pkg/encode/base64.go#L44-L51)
|
||
- [config.go:18-56](file://internal/config/config.go#L18-L56)
|
||
|
||
章节来源
|
||
- [router.go:14-41](file://internal/router/router.go#L14-L41)
|
||
- [main.go:22-95](file://cmd/server/main.go#L22-L95)
|
||
- [README.md:19-123](file://README.md#L19-L123)
|
||
|
||
## 核心组件
|
||
- 路由工厂函数 New:集中初始化 Gin 引擎、注册全局中间件、创建各处理器实例,并完成路由分组与注册。
|
||
- 路由分组:
|
||
- /api/v1:版本化健康检查端点
|
||
- /audio:音频设备相关业务端点
|
||
- 中间件链:Recovery -> RequestID -> Logger -> CORS
|
||
- 统一响应体:OK/Fail/BadRequest/InternalError,保证一致的返回结构
|
||
|
||
章节来源
|
||
- [router.go:14-41](file://internal/router/router.go#L14-L41)
|
||
- [response.go:15-36](file://internal/response/response.go#L15-L36)
|
||
|
||
## 架构总览
|
||
下图展示了从请求进入至响应返回的完整链路,包括中间件执行顺序与处理器调用。
|
||
|
||
```mermaid
|
||
sequenceDiagram
|
||
participant C as "客户端"
|
||
participant G as "Gin 引擎"
|
||
participant R as "路由分组(/api/v1 或 /audio)"
|
||
participant M1 as "中间件 : Recovery"
|
||
participant M2 as "中间件 : RequestID"
|
||
participant M3 as "中间件 : Logger"
|
||
participant M4 as "中间件 : CORS"
|
||
participant H as "处理器"
|
||
C->>G : "HTTP 请求"
|
||
G->>M1 : "进入中间件链"
|
||
M1->>M2 : "继续"
|
||
M2->>M3 : "继续"
|
||
M3->>M4 : "继续"
|
||
M4->>R : "匹配路由分组"
|
||
R->>H : "调用对应处理器"
|
||
H-->>G : "写入响应"
|
||
G-->>C : "HTTP 响应"
|
||
```
|
||
|
||
图表来源
|
||
- [router.go:14-41](file://internal/router/router.go#L14-L41)
|
||
- [logger.go:10-44](file://internal/middleware/logger.go#L10-L44)
|
||
- [request_id.go:20-29](file://internal/middleware/request_id.go#L20-L29)
|
||
- [cors.go:7-19](file://internal/middleware/cors.go#L7-L19)
|
||
|
||
## 详细组件分析
|
||
|
||
### 路由工厂与中间件链
|
||
- 工厂函数 New 创建 Gin 引擎并按顺序注册中间件,确保异常恢复、请求追踪、日志记录与跨域支持贯穿所有路由。
|
||
- 中间件顺序决定日志统计的粒度与错误兜底能力,建议保持现有顺序以获得最佳可观测性与稳定性。
|
||
|
||
章节来源
|
||
- [router.go:14-19](file://internal/router/router.go#L14-L19)
|
||
- [logger.go:10-44](file://internal/middleware/logger.go#L10-L44)
|
||
- [request_id.go:20-29](file://internal/middleware/request_id.go#L20-L29)
|
||
- [cors.go:7-19](file://internal/middleware/cors.go#L7-L19)
|
||
|
||
### 路由分组与端点清单
|
||
- /api/v1 分组
|
||
- GET /api/v1/health → 健康检查
|
||
- /audio 分组
|
||
- GET /audio/getBrand → 品牌列表
|
||
- GET /audio/getModel → 型号列表
|
||
- GET /audio/modelList → 模型搜索列表
|
||
- GET /audio/reportDevInfo → 设备信息上报
|
||
|
||
章节来源
|
||
- [router.go:27-38](file://internal/router/router.go#L27-L38)
|
||
- [README.md:83-110](file://README.md#L83-L110)
|
||
|
||
### 中间件详解
|
||
|
||
#### CORS 中间件
|
||
- 设置允许来源、方法、头字段与暴露头
|
||
- 对预检请求直接返回状态码
|
||
- 放行后续处理器执行
|
||
|
||
章节来源
|
||
- [cors.go:7-19](file://internal/middleware/cors.go#L7-L19)
|
||
|
||
#### 日志中间件
|
||
- 记录请求路径、方法、耗时、状态码、客户端 IP、请求 ID、查询参数与错误信息
|
||
- 按状态码分级输出(info/warn/error)
|
||
|
||
章节来源
|
||
- [logger.go:10-44](file://internal/middleware/logger.go#L10-L44)
|
||
|
||
#### 请求 ID 中间件
|
||
- 从请求头读取或生成唯一标识,注入上下文并回传给客户端
|
||
- 用于全链路追踪与问题定位
|
||
|
||
章节来源
|
||
- [request_id.go:20-29](file://internal/middleware/request_id.go#L20-L29)
|
||
|
||
### 处理器与端点行为
|
||
|
||
#### 健康检查 /api/v1/health
|
||
- 功能:返回服务运行状态
|
||
- 参数:无
|
||
- 返回:统一响应体,data 包含状态字段
|
||
|
||
章节来源
|
||
- [health.go:14-18](file://internal/handler/health.go#L14-L18)
|
||
- [response.go:15-21](file://internal/response/response.go#L15-L21)
|
||
|
||
#### 品牌列表 /audio/getBrand
|
||
- 功能:按品牌名模糊查询品牌列表
|
||
- 查询参数:
|
||
- brandName:品牌名称(可选)
|
||
- base64Resp:是否返回 Base64 编码结果(默认 true)
|
||
- 行为:
|
||
- 调用仓库层查询
|
||
- 可选地对结果进行 JSON 编码后返回
|
||
|
||
章节来源
|
||
- [brand.go:26-49](file://internal/handler/brand.go#L26-L49)
|
||
- [base64.go:44-51](file://pkg/encode/base64.go#L44-L51)
|
||
|
||
#### 型号列表 /audio/getModel
|
||
- 功能:按品牌或型号关键词查询型号列表
|
||
- 查询参数:
|
||
- brandName:品牌名称(可选)
|
||
- modelName:型号名称(可选)
|
||
- base64Resp:是否返回 Base64 编码结果(默认 true)
|
||
- 行为:
|
||
- 调用仓库层查询
|
||
- 可选地对结果进行 JSON 编码后返回
|
||
|
||
章节来源
|
||
- [model.go:26-49](file://internal/handler/model.go#L26-L49)
|
||
- [base64.go:44-51](file://pkg/encode/base64.go#L44-L51)
|
||
|
||
#### 模型搜索列表 /audio/modelList
|
||
- 功能:基于关键字与数量限制进行模型检索
|
||
- 查询参数:
|
||
- key:搜索关键字
|
||
- count:返回条数上限(可选,默认较大值)
|
||
- base64Resp:是否返回 Base64 编码结果(默认 true)
|
||
- 行为:
|
||
- 调用搜索引擎客户端查询
|
||
- 可选地对结果进行 JSON 编码后返回
|
||
|
||
章节来源
|
||
- [model_list.go:26-55](file://internal/handler/model_list.go#L26-L55)
|
||
- [base64.go:44-51](file://pkg/encode/base64.go#L44-L51)
|
||
|
||
#### 设备信息上报 /audio/reportDevInfo
|
||
- 功能:接收设备 MAC、型号、版本与来源 IP,写入缓存
|
||
- 查询参数:
|
||
- mac:设备 MAC 地址(必填)
|
||
- model:设备型号(必填)
|
||
- ver:版本号(可选)
|
||
- 行为:
|
||
- 校验必填参数
|
||
- 组装设备信息并写入缓存
|
||
- 返回统一响应体
|
||
|
||
章节来源
|
||
- [device.go:26-84](file://internal/handler/device.go#L26-L84)
|
||
|
||
### 统一响应体
|
||
- OK:成功响应,code=0,message="ok"
|
||
- Fail:通用错误,携带业务 code 与 message
|
||
- BadRequest:客户端错误
|
||
- InternalError:服务端错误
|
||
|
||
章节来源
|
||
- [response.go:15-36](file://internal/response/response.go#L15-L36)
|
||
|
||
### 路由注册流程(工厂模式)
|
||
- 初始化 Gin 引擎
|
||
- 注册全局中间件(Recovery、RequestID、Logger、CORS)
|
||
- 实例化各处理器(数据库/搜索引擎/缓存客户端注入)
|
||
- 创建路由分组并注册端点
|
||
- 返回引擎供 HTTP 服务器使用
|
||
|
||
```mermaid
|
||
flowchart TD
|
||
Start(["调用 New"]) --> Init["创建 Gin 引擎"]
|
||
Init --> UseRecovery["注册 Recovery 中间件"]
|
||
UseRecovery --> UseReqID["注册 RequestID 中间件"]
|
||
UseReqID --> UseLogger["注册 Logger 中间件"]
|
||
UseLogger --> UseCORS["注册 CORS 中间件"]
|
||
UseCORS --> NewHandlers["创建各处理器实例"]
|
||
NewHandlers --> GroupV1["创建 /api/v1 分组"]
|
||
GroupV1 --> RegHealth["注册 /api/v1/health"]
|
||
NewHandlers --> GroupAudio["创建 /audio 分组"]
|
||
GroupAudio --> RegBrand["注册 /audio/getBrand"]
|
||
GroupAudio --> RegModel["注册 /audio/getModel"]
|
||
GroupAudio --> RegModelList["注册 /audio/modelList"]
|
||
GroupAudio --> RegDevice["注册 /audio/reportDevInfo"]
|
||
RegDevice --> ReturnEngine["返回引擎"]
|
||
```
|
||
|
||
图表来源
|
||
- [router.go:14-41](file://internal/router/router.go#L14-L41)
|
||
|
||
## 依赖关系分析
|
||
- 路由层依赖中间件层与处理器层
|
||
- 处理器层依赖响应体与编码工具
|
||
- 服务启动层负责装配配置、数据库、搜索引擎与缓存,并将它们注入路由工厂
|
||
|
||
```mermaid
|
||
graph LR
|
||
MAIN["cmd/server/main.go"] --> ROUTER["internal/router/router.go"]
|
||
ROUTER --> MW_REQID["internal/middleware/request_id.go"]
|
||
ROUTER --> MW_LOG["internal/middleware/logger.go"]
|
||
ROUTER --> MW_CORS["internal/middleware/cors.go"]
|
||
ROUTER --> H_HEALTH["internal/handler/health.go"]
|
||
ROUTER --> H_BRAND["internal/handler/brand.go"]
|
||
ROUTER --> H_MODEL["internal/handler/model.go"]
|
||
ROUTER --> H_MODELLIST["internal/handler/model_list.go"]
|
||
ROUTER --> H_DEVICE["internal/handler/device.go"]
|
||
H_BRAND --> RESP["internal/response/response.go"]
|
||
H_MODEL --> RESP
|
||
H_MODELLIST --> RESP
|
||
H_DEVICE --> RESP
|
||
H_MODELLIST --> ENCODE["pkg/encode/base64.go"]
|
||
H_BRAND --> ENCODE
|
||
H_MODEL --> ENCODE
|
||
```
|
||
|
||
图表来源
|
||
- [main.go:64](file://cmd/server/main.go#L64)
|
||
- [router.go:21-25](file://internal/router/router.go#L21-L25)
|
||
- [response.go:15-36](file://internal/response/response.go#L15-L36)
|
||
- [base64.go:44-51](file://pkg/encode/base64.go#L44-L51)
|
||
|
||
章节来源
|
||
- [main.go:32-62](file://cmd/server/main.go#L32-L62)
|
||
- [router.go:14-41](file://internal/router/router.go#L14-L41)
|
||
|
||
## 性能考量
|
||
- 中间件顺序与开销
|
||
- Recovery 放在首位,避免重复包裹
|
||
- RequestID/CORS/LR 等轻量中间件顺序合理,尽量减少阻塞
|
||
- 日志中间件
|
||
- 建议仅在必要时记录查询参数,避免大对象日志
|
||
- 控制错误日志频率,防止雪崩
|
||
- 编码优化
|
||
- base64Resp 仅在需要时开启,避免不必要的编码成本
|
||
- 路由分组
|
||
- 将版本化与业务域分离,便于未来扩展与限流策略落地
|
||
|
||
## 故障排查指南
|
||
- 健康检查失败
|
||
- 检查 /api/v1/health 是否可达
|
||
- 关注日志中间件输出的状态码与耗时
|
||
- CORS 相关问题
|
||
- 确认浏览器预检请求已正确处理
|
||
- 核对允许的方法与头字段
|
||
- 请求 ID 未返回
|
||
- 检查客户端是否正确传递与读取 X-Request-ID
|
||
- 处理器错误
|
||
- 查看处理器日志中的错误字段
|
||
- 使用统一响应体的 code/message 定位问题
|
||
- 编码异常
|
||
- base64Resp 开启时确认客户端解析逻辑
|
||
|
||
章节来源
|
||
- [logger.go:33-43](file://internal/middleware/logger.go#L33-L43)
|
||
- [request_id.go:22-27](file://internal/middleware/request_id.go#L22-L27)
|
||
- [cors.go:9-12](file://internal/middleware/cors.go#L9-L12)
|
||
- [response.go:23-36](file://internal/response/response.go#L23-L36)
|
||
|
||
## 结论
|
||
本路由系统采用清晰的工厂模式与中间件链设计,结合版本化与业务域分组,具备良好的可维护性与扩展性。遵循现有中间件顺序与统一响应体规范,有助于提升可观测性与稳定性。建议在新增端点时严格复用现有中间件与响应体,确保一致性与性能。
|
||
|
||
## 附录
|
||
|
||
### 端点一览与参数说明
|
||
- /api/v1/health
|
||
- 方法:GET
|
||
- 参数:无
|
||
- 返回:统一响应体
|
||
- /audio/getBrand
|
||
- 方法:GET
|
||
- 参数:
|
||
- brandName:字符串(可选)
|
||
- base64Resp:布尔或数字字符串(可选,默认 true)
|
||
- 返回:统一响应体
|
||
- /audio/getModel
|
||
- 方法:GET
|
||
- 参数:
|
||
- brandName:字符串(可选)
|
||
- modelName:字符串(可选)
|
||
- base64Resp:布尔或数字字符串(可选,默认 true)
|
||
- 返回:统一响应体
|
||
- /audio/modelList
|
||
- 方法:GET
|
||
- 参数:
|
||
- key:字符串(必填)
|
||
- count:整数(可选,默认较大值)
|
||
- base64Resp:布尔或数字字符串(可选,默认 true)
|
||
- 返回:统一响应体
|
||
- /audio/reportDevInfo
|
||
- 方法:GET
|
||
- 参数:
|
||
- mac:字符串(必填)
|
||
- model:字符串(必填)
|
||
- ver:字符串(可选)
|
||
- 返回:统一响应体
|
||
|
||
章节来源
|
||
- [router.go:29](file://internal/router/router.go#L29)
|
||
- [brand.go:27-28](file://internal/handler/brand.go#L27-L28)
|
||
- [model.go:27-28](file://internal/handler/model.go#L27-L28)
|
||
- [model_list.go:27-35](file://internal/handler/model_list.go#L27-L35)
|
||
- [device.go:27-28](file://internal/handler/device.go#L27-L28)
|
||
|
||
### 中间件链路分析(序列图)
|
||
```mermaid
|
||
sequenceDiagram
|
||
participant Client as "客户端"
|
||
participant Engine as "Gin 引擎"
|
||
participant Recovery as "Recovery"
|
||
participant ReqID as "RequestID"
|
||
participant Logger as "Logger"
|
||
participant CORS as "CORS"
|
||
participant Handler as "处理器"
|
||
Client->>Engine : "请求"
|
||
Engine->>Recovery : "进入"
|
||
Recovery->>ReqID : "继续"
|
||
ReqID->>Logger : "继续"
|
||
Logger->>CORS : "继续"
|
||
CORS->>Handler : "匹配路由并调用"
|
||
Handler-->>Engine : "写入响应"
|
||
Engine-->>Client : "响应"
|
||
```
|
||
|
||
图表来源
|
||
- [router.go:16-19](file://internal/router/router.go#L16-L19)
|
||
- [logger.go:16](file://internal/middleware/logger.go#L16)
|
||
- [request_id.go:28](file://internal/middleware/request_id.go#L28)
|
||
- [cors.go:18](file://internal/middleware/cors.go#L18) |