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

4.5 KiB
Raw Blame History

3.7 路由与元数据注册(RouteSpec)

:::tip 概述 本项目的路由只有一处声明:router.go 内每个控制器的 RouteSpec 表。注册、权限校验、操作日志、公开白名单、OpenAPI 文档全部从这一份声明派生,天然同步。 :::

RouteSpec 字段

// internal/router/bind.go
type RouteSpec struct {
    Method     string // HTTP 方法:GET/POST/PUT/DELETE(必填,否则不注册)
    Path       string // 路由模板,如 /api/link/detail/:id(必填)
    Summary    string // 接口摘要(OpenAPI)
    Permission string // 权限节点 sys:link:page;空表示登录即可
    Log        string // 操作日志标题;空表示不记录
    LogType    string // 日志类型:query/add/update/delete/import/export/reset…
    Public     bool   // 免登录(登录、验证码等)
}

注册写法

在 internal/router/router.go 的 registerControllers 内,为控制器集中声明(方法名 → 路由元数据,按字典序排列):

// internal/router/router.go
Bind(rg, new(handler.CExample), map[string]RouteSpec{
    "Add":         {Method: "POST", Path: "/api/example/add", Summary: "新增案例演示", Permission: "sys:example:add", Log: "案例演示-新增记录", LogType: "add"},
    "BatchDelete": {Method: "DELETE", Path: "/api/example/batchDelete", Summary: "批量删除案例演示", Permission: "sys:example:batchDelete", Log: "案例演示-批量删除记录", LogType: "delete"},
    "Delete":      {Method: "DELETE", Path: "/api/example/delete/:id", Summary: "删除案例演示", Permission: "sys:example:delete", Log: "案例演示-删除记录", LogType: "delete"},
    "Detail":      {Method: "GET", Path: "/api/example/detail/:id", Summary: "案例演示详情", Permission: "sys:example:detail", Log: "案例演示-查询详情", LogType: "query"},
    "Export":      {Method: "GET", Path: "/api/example/export", Summary: "导出案例演示", Permission: "sys:example:export", Log: "案例演示-导出数据", LogType: "export"},
    "Import":      {Method: "POST", Path: "/api/example/import", Summary: "导入案例演示", Permission: "sys:example:import", Log: "案例演示-导入数据", LogType: "import"},
    "List":        {Method: "GET", Path: "/api/example/list", Summary: "案例演示列表", Permission: "sys:example:list", Log: "案例演示-查询列表", LogType: "query"},
    "Page":        {Method: "GET", Path: "/api/example/page", Summary: "案例演示分页", Permission: "sys:example:page", Log: "案例演示-查询分页记录", LogType: "query"},
    "Status":      {Method: "PUT", Path: "/api/example/status", Summary: "案例演示状态", Permission: "sys:example:status", Log: "案例演示-设置状态", LogType: "update"},
    "Update":      {Method: "PUT", Path: "/api/example/update", Summary: "修改案例演示", Permission: "sys:example:update", Log: "案例演示-修改记录", LogType: "update"},
})

注册后发生什么

router.Bind 反射扫描控制器:

按签名筛选方法(ctx, *dto.Req)→(*dto.Res, error)
        │
        ▼
按方法名查 RouteSpec 表 → rg.Handle(Method, Path, 包装函数)
        │
        ▼
包装函数内:绑定解析(path > body > query)→ binding 校验 → 调 handler → 信封响应
        │
        ▼
写入路由元数据表(方法名、路径、权限码、日志配置、公开标记)
        │
        ▼
authz / operation_log / public / OpenAPI 从元数据表消费同一份声明

声明规约

项 规约
路径 /api/{模块}/{动作},路径参数用 :id
方法映射 查询 GET / 新增 POST / 修改 PUT / 删除 DELETE
权限码 sys:{模块}:{动作},动作与路径动词一致
Permission 为空 登录即可访问(不校验权限点)
Log 为空 不记录操作日志;查询类是否记录还受 operationLog.logQuery 开关控制
Public 仅登录、验证码、令牌兑换等真正公开接口使用
顺序 表内按方法名字典序排列,与既有条目风格逐字一致

新增接口的完整动作

  1. dto 加请求/响应结构
  2. service 加方法
  3. handler 加同签名方法
  4. RouteSpec 表加一条声明
  5. 需要权限点时在菜单管理中配置权限节点(见下一页)

底层机制深入

反射细节、元数据表结构、中间件如何消费元数据 → 4.4 反射元数据驱动机制。

下一步

→ 3.8 参数校验与错误上抛