Skip to content

3.6 控制器开发 ​

概述

控制器是 HTTP 薄层,只做一件事:把解析好的请求转发给 service 接口。不写业务、不操作数据库、不组装复杂响应——所有逻辑在 logic 层。这个"薄"是有意为之:让权限、日志、参数解析统一收敛到 Bind 包装层。

真实代码(摘自 internal/controller/example.go) ​

go
package controller

import (
	"context"

	"easygoadmin/api/v1"
	"easygoadmin/internal/service"
)

// ============================== 案例演示控制器 ==============================

// CExample 案例演示控制器
// 薄层控制器,仅负责参数透传,业务逻辑由 service.Example() 处理
type CExample struct{}

// Page 案例演示分页
// 按查询条件分页返回案例演示列表
func (c *CExample) Page(ctx context.Context, req *v1.ExamplePageReq) (res *v1.ExamplePageRes, err error) {
	return service.Example().Page(ctx, req)
}

// List 案例演示平铺列表
// data 直接为数组,树形结构由前端 buildTree 构建
func (c *CExample) List(ctx context.Context, req *v1.ExampleListReq) (res v1.ExampleListRes, err error) {
	return service.Example().List(ctx, req)
}

// Detail 案例演示详情
// 按主键ID查询详情
func (c *CExample) Detail(ctx context.Context, req *v1.ExampleDetailReq) (res *v1.ExampleDetailRes, err error) {
	return service.Example().Detail(ctx, req)
}

// Add 新增案例演示
// 新增成功后返回新记录ID
func (c *CExample) Add(ctx context.Context, req *v1.ExampleAddReq) (res *v1.ExampleIdRes, err error) {
	return service.Example().Add(ctx, req)
}

// Update 修改案例演示
// 按主键ID更新记录
func (c *CExample) Update(ctx context.Context, req *v1.ExampleUpdateReq) (res *v1.ExampleUpdateRes, err error) {
	return service.Example().Update(ctx, req)
}

// Status 案例演示状态
// 设置记录的状态字段
func (c *CExample) Status(ctx context.Context, req *v1.ExampleStatusReq) (res *v1.ExampleStatusRes, err error) {
	return service.Example().Status(ctx, req)
}

方法签名约定 ​

go
func (c *CXxx) 方法名(ctx context.Context, req *v1.XxxReq) (res *v1.XxxRes, err error)

这是 Bind 反射绑定的硬约束:入参必须是指针请求结构体,出参必须是(结果指针, error)。签名不匹配的方法不会被注册路由(静默跳过),排障时注意。

命名规则 ​

项规则示例
控制器类型C + 模块 PascalCExample、CConfigItem
文件名表名去前缀 snake_caseexample.go、config_item.go
方法名与 logic/接口方法名一致Page/Add/BatchDelete
包单包 controller,平铺放置无子目录

控制器里禁止做的事 ​

薄层纪律

  1. 禁止写业务逻辑——if/for/计算全部下沉 logic。
  2. 禁止直接 import dao——数据访问只在 logic。
  3. 禁止手写响应信封——Bind 包装层统一 response.Ok/Fail 包装。
  4. 禁止手写参数解析/权限判断——r.Parse 与 HasPerm 在包装层完成。
  5. 需要组合多个 service 调用时,逻辑放 logic 层的一个聚合方法,controller 仍只透传。

特殊控制器参考 ​

控制器特点
CAuth登录/登出/验证码/令牌,gmeta 带 public:"true"
CIndex个人中心聚合(getUser/getMenus/updatePassword/updateProfile)
COnlineUser无表模块,数据源 Redis
CUploadmultipart 上传(*ghttp.UploadFile + p:"file" 标签)
CGenerator工具类,Preview/Generate/BatchGenerate

控制器不区分"标准/特殊"写法——统一薄层透传,差异全部体现在请求结构体的 gmeta 注解上。

小蚂蚁云团队 · 提供技术支持