Files
easygoadmin-wiki/EasyGoAdmin_Gin_AntdVue/zh/architecture/request-flow.md
T
2026-10-25 17:24:27 +08:00

113 lines
3.8 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.
# 4.2 请求处理链路
:::tip 链路概览
一个典型 API 请求经过:浏览器 →(Nginx/Vite 代理)→ 中间件链 → 反射路由绑定 → handler → service → repository → 数据库 → 统一信封返回。本页以 `GET /api/example/page` 为例逐阶段拆解。
:::
## 第一阶段:网络层
前端经封装发起请求(`ui/src/api/tool/example.ts`):
```typescript
// ui/src/api/tool/example.ts(摘录)
import { http } from '@/utils/http/axios';
// Authorization: Bearer <access_token> 由请求拦截器自动携带
export function getExamplePage(params?: Record<string, any>) {
return http.request({ url: '/example/page', method: 'GET', params });
}
```
开发期 Vite 代理转发(`ui/.env.development`):
```text
VITE_PROXY=[["/api", "http://127.0.0.1:8000/api"]]
```
生产由 Nginx 反代到 8000(见 deploy/nginx.conf)。
## 第二阶段:中间件链(顺序勿动)
```text
trace 分配 trace_id,后续全部日志可关联
↓
CORS 跨域响应头(cors.allowOrigin)
↓
Metrics Prometheus 指标采集(请求数/耗时)
↓
Response 统一信封出口 + panic 恢复(必须包住其后全部 handler)
↓
RateLimit 固定窗口限流(认证接口配额更严)
↓
Demo 演示模式:写操作拒绝,读与登录放行
↓
JWT 解析 Token,注入身份(公开接口跳过)
↓
Tenant 加载租户上下文(白名单表隔离依据)
↓
Authz 按路由元数据 Permission 校验权限点
↓
OperationLog 采集请求摘要,链尾异步落库(须读到最终响应)
```
顺序是设计约束:trace 最先(日志依赖 trace_id);Response 在业务前(panic 恢复包住全链);限流/演示在身份前(防未认证高频攻击);JWT → 租户 → 权限逐层依赖前置注入的身份;日志链尾采集。
## 第三阶段:路由绑定
`router.Bind` 已在启动期把 `GET /api/example/page` 注册到 Gin 路由树。请求命中后,包装函数执行:
```text
绑定写入:query(pageNo/pageSize/name/type/status/keyword)→ body → path
│ 同名后写覆盖,最终 path > body > query
▼
binding 标签校验(失败直接 4xx 信封返回,不进 handler)
│
▼
构造 dto.ExamplePageReq → 调用 CExample.Page
```
## 第四阶段:四件套调用
```go
// handler:一行委托
service.Example.Page(ctx, req)
// service:委托基座
list, total, err := exampleSpec.Page(ctx, req, req.GetPageNo(), req.GetPageSize())
// ModuleSpec:applyFilters 固定顺序生效
Model(Ctx 已注入 del_flag=0)→ LikeFields(name) → EqFields(type,status)
→ KeywordFields → Filter → DataScope → OrderBy → 分页 Find
```
ctx 贯穿全链——身份、租户、事务连接都挂在 ctx 上,repository 经 `db.FromContext(ctx)` 取连接。
## 第五阶段:响应与日志
```text
service 返回 PageData[ExampleItem]
↓
绑定层包装函数调用 response.Ok(data)
↓
Response 中间件信封输出 {code:0, ok:true, msg, data}
↓
OperationLog 中间件读取最终响应摘要,异步写 gin_operation_log
(LogType=query 时还受 operationLog.logQuery 开关控制)
```
失败路径:binding 校验失败 / apperr 错误 / 普通 error / panic,全部经 Response 中间件映射为对应 code 的 JSON 信封,绝不出现 HTML 错误页(NoRoute 也返回 JSON)。
## 关键观察点
| 阶段 | 观察手段 |
|---|---|
| 全链追踪 | 响应头/日志中的 trace_id |
| SQL | `database.default.debug=true` 打印 SQL |
| 权限 | Swagger(/swagger)查看接口权限码 |
| 指标 | /metrics 看请求计数与耗时分布 |
| 日志落库 | gin_operation_log 表 |
## 下一步
→ [4.3 后端分层架构](/zh/architecture/backend-layer.html)