2.9 KiB
2.9 KiB
3.6 接口层开发(handler)
:::tip 概述
handler 是极薄委托层:router.Bind 反射已完成参数解析与 binding 校验,本层只做一次调用转换。业务规则一律在 service,handler 不写逻辑。
:::
标准结构
// internal/handler/example.go
package handler
import (
"context"
"easygoadmin/internal/model/dto"
"easygoadmin/internal/service"
)
// CExample 案例演示控制器
type CExample struct{}
// Page 案例演示分页(GET /api/example/page),委托 service.Example.Page
func (c *CExample) Page(ctx context.Context, req *dto.ExamplePageReq) (*dto.PageData[dto.ExampleItem], error) {
return service.Example.Page(ctx, req)
}
// Add 新增案例演示(POST /api/example/add),委托 service.Example.Add
func (c *CExample) Add(ctx context.Context, req *dto.ExampleAddReq) (*dto.ExampleIdRes, error) {
return service.Example.Add(ctx, req)
}
方法签名铁律
每个对外方法签名必须是:
func (c *CXxx) Method(ctx context.Context, req *dto.XxxReq) (*dto.XxxRes, error)
路由反射扫描靠这个签名识别方法并绑定请求——签名不匹配的方法不会被注册(也不会报错,表现为 404)。返回值可以是结构体指针、类型别名(如 dto.ExampleListRes)或 *dto.EmptyRes。
手写逻辑方法的注释规约
非标准方法(导入/导出/重置密码/分配菜单等)保留为 handler 方法,按"入参/返回/副作用"三段注释:
// internal/handler/example.go
// Import 导入案例演示(POST /api/example/import),委托 service.Example.Import
// 入参:multipart 表单 xls/xlsx 文件(dto 实现 UnmarshalBody 解析文件字段)。
// 返回:导入总数、成功数、失败数及失败原因列表;错误:文件缺失或格式非法时上抛。
// 副作用:解析表格并批量写入案例演示表。
func (c *CExample) Import(ctx context.Context, req *dto.ExampleImportReq) (*dto.ExampleImportRes, error) {
return service.Example.Import(ctx, req)
}
handler 不做的事
| 禁则 | 去处 |
|---|---|
| 参数解析与校验 | router.Bind(binding 标签驱动)+ dto |
| 权限判断 | authz 中间件(RouteSpec.Permission 声明) |
| 操作日志 | operation_log 中间件(RouteSpec.Log 声明) |
| 业务规则与事务 | service |
| 数据访问 | repository(经 service 调用) |
新控制器接入
在 internal/router/router.go 的 registerControllers 中加一条 Bind 声明(含 RouteSpec 表)——见下一页 3.7 路由与元数据注册。代码生成器会自动完成这一步。
编写检查清单
- 控制器名
CXxx,空结构体 - 方法与 dto 请求结构一一对应,签名完全匹配
- 方法体只有一行委托(或极少量调用转换)
- 注释给出路由方法与路径