go-zero(五) 模板定制

go zero 模板定制

go-zero 提供的 goctl 工具能够根据 API 定义自动生成服务框架代码,但在实际项目中,我们往往需要根据团队规范和业务逻辑定制生成的代码。

例如,我们刚刚的使用错误管理,我们需要在handler中返回的错误信息。

一、 go-zero 模板介绍

1.1 模板原理

goctl 的代码生成是基于 Go 标准库的 text/template 实现的,它通过对模板文件中的占位符进行替换,生成最终的代码文件。模板系统使用了以下几个核心概念:

  • 变量:通过 {{.VariableName}} 语法在模板中使用
  • 条件语句:如 {{if .Condition}}...{{else}}...{{end}}
  • 循环:如 {{range .Items}}...{{end}}
  • 函数:如 {{.FunctionName}}

1.2 模板文件组织

goctl 的模板文件按照不同的服务类型进行组织,主要包括:

```
├─api         # API 服务相关模板
├─docker      # Docker 相关配置模板
├─gateway     # 网关服务模板
├─kube        # Kubernetes 配置模板
├─model       # 数据模型相关模板
├─mongo       # MongoDB 相关模板
├─newapi      # 新版 API 服务模板
└─rpc         # RPC 服务相关模板
```

每种服务类型的模板又包含多个子模板,以 API 服务为例:

```
api/
├─handler.tpl     # 处理 HTTP 请求的 handler
├─logic.tpl       # 业务逻辑处理
├─etc.tpl         # 配置文件
├─main.tpl        # 主入口文件
└─...             # 其他模板
```

二、初始化模板文件

首先,我们需要初始化模板文件。通过运行goctl template init 命令,可以将模板文件下载到本地。

sql2pb>goctl template init -home ./
  • home 是存储模板的路径

执行命令后,指定目录中会生成以下文件和文件夹结构:

├─api
├─docker
├─gateway
├─kube
├─model
├─mongo
├─newapi
└─rpc

这些目录对应了go zero中不同模块的模板,提供了服务生成的基本结构。

2.2 模板变量说明

在修改模板前,我们需要了解模板中可以使用的变量。以 handler.tpl 为例,常用的变量包括:

变量名说明
.PkgName包名
.ImportPackages需要导入的包
.HandlerName处理函数名称
.LogicName逻辑层包名
.LogicType逻辑结构体名称
.RequestType请求结构体类型
.HasRequest是否有请求参数
.HasResp是否有响应结构体
.Call调用逻辑层的方法名
.HasDoc是否有文档注释
.Doc文档注释内容

三、修改模板

3.1 错误处理定制示例

这里我们演示如何修改handler.tpl模板,以便在处理请求时返回更合适的错误信息。

打开handler.tpl文件,可以看到生成的代码框架。我们将在处理请求时引入新的错误处理逻辑,使其更符合业务需求。以下是修改后的模板代码:

package {{.PkgName}}

import (
	"net/http"
	xhttp "github.com/zeromicro/x/http"  //导入zeromicro库
	"github.com/zeromicro/go zero/rest/httpx"
	{{.ImportPackages}}
)

{{if .HasDoc}}{{.Doc}}{{end}}
func {{.HandlerName}}(svcCtx *svc.ServiceContext) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		{{if .HasRequest}}var req types.{{.RequestType}}
		if err := httpx.Parse(r, &req); err != nil {
			//httpx.ErrorCtx(r.Context(), w, err)
			xhttp.JsonBaseResponseCtx(r.Context(), w, err)
			return
		}

		{{end}}l := {{.LogicName}}.New{{.LogicType}}(r.Context(), svcCtx)
		{{if .HasResp}}resp, {{end}}err := l.{{.Call}}({{if .HasRequest}}&req{{end}})
		if err != nil {
			//httpx.ErrorCtx(r.Context(), w, err)
			xhttp.JsonBaseResponseCtx(r.Context(), w, err)
		} else {
			{{if .HasResp}}xhttp.JsonBaseResponseCtx(r.Context(), w, resp){{else}}httpx.Ok(w){{end}}
		}
	}
}

修改说明

  • 我们使用了 xhttp.JsonBaseResponseCtx 方法来返回错误信息,这样可以确保客户端得到统一风格的错误响应。
  • 处理请求的逻辑保留了原有结构,但在错误处理的方式上作了调整,以更好地符合业务需求。

自定义规则:

  • 在 goctl 提供的有效数据范围内修改,即不支持外部变量
  • 不支持新增模板文件
  • 不支持变量修改

3.2 根据模板生成代码

完成模板的修改后,可以使用 goctl命令来生成新代码。以下是命令示例:

goctl api go --api user.api --dir ./  --home ../sql2pb    

--home 指定我们刚刚下载的模板路径, 默认值为 ${HOME}/.goctl

在代码生成完成后,我们可以查看生成的 handler 文件,以确认我们的修改是否成功。新的 handler 文件应当能够根据我们自定义的模板返回整洁的错误响应。

在这里插入图片描述

四、高级模板定制技巧

4.1 条件模板生成

我们可以根据 API 定义中的特定注解或标签,动态调整生成的代码:

{{if .HasAuth}}
// 添加认证中间件
server.Use(middleware.Auth())
{{end}}

4.2 自定义函数

goctl 允许在模板中使用自定义函数,例如:

{{$tableName := .Table | snakeCase}}  // 转换为蛇形命名

要实现这一点,需要在 goctl 命令中注册自定义函数。

4.3 多环境模板

为不同的环境(如开发、测试、生产)准备不同的模板,可以通过修改 goctl 命令的参数来实现:

goctl api go --api user.api --dir ./ --home ../templates/dev  # 开发环境模板
goctl api go --api user.api --dir ./ --home ../templates/prod  # 生产环境模板
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值