Files
quyun-v2/backend
..
2025-12-15 17:55:32 +08:00
2025-12-18 18:27:23 +08:00
2025-12-15 17:55:32 +08:00
2025-12-18 18:27:23 +08:00
2025-12-15 17:55:32 +08:00
2025-12-17 22:28:47 +08:00
2025-12-15 17:55:32 +08:00
2025-12-17 09:32:05 +08:00
2025-12-15 17:55:32 +08:00
2025-12-15 17:55:32 +08:00
2025-12-15 17:55:32 +08:00
2025-12-15 17:55:32 +08:00
2025-12-15 17:55:32 +08:00
2025-12-15 17:55:32 +08:00
2025-12-15 17:55:32 +08:00
2025-12-17 09:32:05 +08:00
2025-12-15 17:55:32 +08:00
2025-12-15 17:55:32 +08:00
2025-12-18 10:27:40 +08:00
2025-12-15 17:55:32 +08:00
2025-12-18 17:39:14 +08:00
2025-12-15 17:55:32 +08:00
2025-12-18 10:27:40 +08:00
2025-12-15 17:55:32 +08:00
2025-12-15 17:55:32 +08:00

路由生成gen route

通过在控制器方法上编写注释,解析器从 Go AST 中读取注释、方法签名与参数列表,自动生成路由注册与参数绑定代码。

  • 核心标签:@Router 定义路径与方法;@Bind 定义方法参数的来源与键名。
  • 生成行为:输出 router.<METHOD>(path, FuncN(...))DataFuncN(...) 包装调用,并自动汇聚所需 imports 与控制器注入字段。

快速开始

atomctl gen route [path]
  • 生成文件:当前包目录下 routes.gen.go
  • 分组与排序:按控制器分组,导入、方法、路由项稳定排序,便于审阅 diff。

注释语法

  • @Router <path> [<method>]

    • 示例:@Router /users/:id [get]
  • @Bind <paramName> <position> [key(<key>)] [model(<field>|<model>[:<field>])]

    • paramName 与方法参数名一致(大小写敏感)
    • positionpathquerybodyheadercookielocalfile
    • 可选:
      • key() 覆盖默认键名;
      • model() 详见“模型绑定”。

参数绑定规则(按 position

  • query标量用 QueryParam[T]("key"),非标量用 Query[T]("key")
  • path标量用 PathParam[T]("key"),非标量用 Path[T]("key")
    • 若使用 model()(仅在 path 有效),会按字段值查询并绑定为 T,详见下文
  • headerHeader[T]("key")
  • bodyBody[T]("key")
  • cookiestringCookieParam("key"),其他用 Cookie[T]("key")
  • fileFile[multipart.FileHeader]("key")
  • localLocal[T]("key")

说明:

  • 标量类型集合:stringintint32int64float32float64bool
  • key 默认等于 paramName;设置 key(...) 后以其为准
  • file 使用固定类型 multipart.FileHeader

类型与指针处理

  • 支持 T*Tpkg.T*pkg.T;会正确收集选择子表达式对应 import
  • 忽略结尾为 ContextCtx 的参数(框架上下文)
  • 指针处理:除 local 外会去掉前导 * 作为泛型实参;local 保留指针(便于写回)

解析与匹配

  • 先收集注释中的多条 @Bind,再按“方法参数列表顺序”匹配并输出绑定器,确保调用顺序与方法签名一致
  • 未在方法参数中的 @Bind 会被忽略;缺失 @Router 或方法无注释将跳过该方法
  • import 自动收集去重;控制器注入字段名为类型名的小驼峰形式,例如 userController *UserController

返回值与包装函数

  • 返回值个数 > 1使用 DataFuncN
  • 否则使用 FuncN
  • N 为参与绑定的参数个数

模型绑定path + model

@Bind ... model(...) 配合 position=path 使用时,将根据路径参数值查询模型并绑定为方法参数类型的实例(T 来自方法参数)。

  • 语法:
    • 仅字段:model(id)(推荐)
    • 指定字段与类型:model(id:int)model(code:string)(用于非字符串路径参数)
    • 指定类型与字段:model(pkg.Type:field)model(pkg.Type)(字段缺省为 id
  • 行为:
    • 生成的绑定器会按给定字段构造查询条件并返回首条记录
    • 自动注入 importfield "go.ipao.vip/gen/field",用于构造字段条件表达式

示例:

// @Router /users/:id [get]
// @Bind user path key(id) model(id)
func (uc *UserController) Show(ctx context.Context, user *models.User) (*UserDTO, error)

完整示例

注释与方法签名:

// @Router /users/:id [get]
// @Bind user path key(id) model(id)
// @Bind fields query
// @Bind token header key(Authorization)
// @Bind sess cookie key(session_id)
// @Bind cfg local
func (uc *UserController) GetUser(ctx context.Context, user *models.User, fields []string, token string, sess string, cfg *AppConfig) (*User, error)

生成的路由注册(示意):

router.Get("/users/:id", DataFunc4(
    r.userController.GetUser,
    PathModel[models.User]("id", "id"),
    Query[[]string]("fields"),
    Header[string]("Authorization"),
    CookieParam("session_id"),
))

错误与限制

  • 无效的 @Router 语法会报错;无效的 position 会在解析阶段触发错误
  • file 仅支持单文件头;model() 仅在 position=path 时参与代码生成
  • 请确保路由段变量名与 key(...) 保持一致