goctl 代码生成
goctl 是 go-zero 的核心生产力工具,通过声明式的 DSL 文件(.api / .proto / DDL)一键生成服务脚手架、数据库模型、Dockerfile 和 K8s 部署文件。
goctl 命令总览
goctl --help| 命令 | 功能 |
|---|---|
goctl api |
从 .api 文件生成 HTTP 服务 |
goctl rpc |
从 .proto 文件生成 gRPC 服务 |
goctl model |
从 DDL / 数据库生成 CRUD + 缓存代码 |
goctl docker |
生成 Dockerfile |
goctl kube |
生成 K8s 部署 YAML |
goctl template |
管理代码生成模板 |
goctl env |
查看/设置 goctl 环境变量 |
goctl migrate |
迁移旧版本配置到新版本 |
goctl upgrade |
升级 goctl 到最新版本 |
goctl completion |
生成 shell 自动补全脚本 |
api 子命令:HTTP 服务
api new — 创建新服务
goctl api new user生成一个最简 Hello World 服务(包含 .api 文件和完整项目结构)。
api go — 从 DSL 生成代码
goctl api go -api user.api -dir .| 参数 | 说明 |
|---|---|
-api |
.api 文件路径 |
-dir |
输出目录 |
-style |
文件名风格:gozero(默认)/ go_zero / GoZero |
-home |
goctl 模板目录(默认 ~/.goctl) |
-remote |
远程 git 仓库模板 |
生成其他语言客户端
goctl api java -api user.api -dir ./client-java
goctl api dart -api user.api -dir ./client-dart
goctl api ts -api user.api -dir ./client-ts新增接口后增量生成
# 修改 .api 文件后重新执行
goctl api go -api user.api -dir .💡 增量生成不会覆盖
logic/文件夹中的已有文件,只会更新handler/、types/和routes.go。新接口会自动生成新的 logic 文件。
rpc 子命令:gRPC 服务
rpc new — 创建新服务
goctl rpc new userrpc protoc — 从 proto 生成代码
# 基础用法
goctl rpc protoc user.proto --go_out=./ --go-grpc_out=./ --zrpc_out=./
# 多 service 分组模式
goctl rpc protoc user.proto --go_out=./ --go-grpc_out=./ --zrpc_out=./ -m
# 自定义输出目录
goctl rpc protoc user.proto --go_out=./pb --go-grpc_out=./pb --zrpc_out=./ -m| 参数 | 说明 |
|---|---|
--go_out |
protobuf 类型代码输出目录 |
--go-grpc_out |
gRPC 桩代码输出目录 |
--zrpc_out |
go-zero RPC 脚手架(logic/server/config)输出目录 |
-m |
启用多 service 分组(proto 中有多个 service 时必须加) |
-style |
文件命名风格 |
-home |
模板目录 |
-remote |
远程模板 |
rpc template — 生成 proto 模板
goctl rpc template -o user.protomodel 子命令:数据库模型
goctl model 是最能体现 go-zero “工具大于约定” 理念的功能。
从 DDL 文件生成
goctl model mysql ddl -c -src user.sql -dir .| 参数 | 说明 |
|---|---|
-c |
启用 Redis 缓存(不传则只生成纯 SQL 访问) |
-src |
DDL 文件路径(支持 *.sql 通配符) |
-dir |
输出目录 |
-style |
文件命名风格 |
-home |
模板目录 |
从数据库直接生成
goctl model mysql datasource \
-url "root:password@tcp(127.0.0.1:3306)/dbname" \
-table "user,order" \
-c \
-dir ./model| 参数 | 说明 |
|---|---|
-url |
MySQL DSN |
-table |
要生成的表名,逗号分隔(区分大小写!) |
-c |
启用缓存 |
-dir |
输出目录 |
生成的文件
model/
├── usermodel_gen.go # 自动生成(可被覆盖):基础 CRUD + 缓存逻辑
├── usermodel.go # 自定义扩展(不会被覆盖):复杂查询、事务
└── vars.go # 表名、字段名常量usermodel_gen.go 内含:
Insert(ctx, data)— 插入一条记录并清缓存FindOne(ctx, id)— 按主键查(先缓存后 DB)Update(ctx, data)— 更新并清缓存Delete(ctx, id)— 删除并清缓存FindOneByXxx(ctx, ...)— 按唯一索引查询
usermodel.go 用于扩展:
// 自定义批量查询方法
func (m *defaultUserModel) FindByIds(ctx context.Context, ids []int64) ([]*User, error) {
query := fmt.Sprintf("SELECT * FROM %s WHERE id IN (%s)", m.table, placeholders)
// ...
}🚨 表名区分大小写:
-table "User"是错的(如果 MySQL 表名为user),必须写-table "user"。
docker 子命令
goctl docker -go user.go生成多阶段构建的 Dockerfile:
FROM golang:1.21-alpine AS builder
WORKDIR /app
COPY . .
RUN go build -o user user.go
FROM alpine:latest
RUN apk add --no-cache ca-certificates tzdata
COPY --from=builder /app/user /app/user
COPY --from=builder /app/etc /app/etc
CMD ["/app/user"]kube 子命令
goctl kube deploy \
-name user \
-namespace default \
-image user:latest \
-secret docker-registry \
-port 8080 \
-nodePort 30080 \
-requestCpu 100 \
-requestMem 50 \
-limitCpu 200 \
-limitMem 100 \
-replicas 3 \
-o user-deploy.yaml生成的 K8s YAML 包含 Deployment、Service、Secret 等资源。
自定义模板
模板存放位置
~/.goctl/<version>/
├── api/
│ ├── config.tpl
│ ├── handler.tpl
│ ├── logic.tpl
│ ├── main.tpl
│ ├── routes.tpl
│ └── ...
├── rpc/
│ ├── config.tpl
│ ├── logic.tpl
│ ├── main.tpl
│ └── ...
└── model/
└── ...使用自定义模板
# 初始化模板到本地
goctl template init --home ./templates
# 修改模板后使用
goctl api go -api user.api -dir . -home ./templates自定义模板示例
修改 ~/.goctl/api/handler.tpl,注入统一错误处理:
package handler
import (
"net/http"
{{.ImportPackages}}
)
func {{.HandlerName}}(ctx *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 {
xhttp.ParamErrorResult(r, w, err) // 使用自定义错误处理
return
}
{{end}}
l := logic.New{{.LogicType}}(r.Context(), ctx)
resp, err := l.{{.Call}}({{if .HasRequest}}req{{end}})
xhttp.HttpResult(r, w, resp, err) // 统一格式化响应
}
}💡 团队内部强烈建议统一定制模板,避免每个人手写不同风格的 Handler 代码。
goctl 环境变量
# 查看环境变量
goctl env
# 设置环境变量
goctl env set GOPATH /path/to/go常用环境变量:
| 变量 | 说明 | 默认值 |
|---|---|---|
GOCTL_HOME |
goctl 模板和缓存目录 | ~/.goctl |
GOPATH |
Go 工作空间 | 系统 GOPATH |
GOCTL_EXPERIMENTAL |
启用实验性功能 | off |
版本升级
# 升级 goctl
goctl upgrade
# 升级到指定版本
go install github.com/zeromicro/go-zero/tools/goctl@v1.10.0
# 迁移旧配置
goctl migrate --home ~/.goctl代码生成工作流
团队推荐的标准工作流:
1. 设计 API DSL
→ 编写 .api 文件
→ 团队 review DSL 定义
2. 生成 API 服务
→ goctl api go -api user.api -dir .
→ 填充 logic/ 中的业务逻辑
3. 设计 Proto
→ 编写 .proto 文件
4. 生成 RPC 服务
→ goctl rpc protoc user.proto --zrpc_out=.
→ 填充 logic/ 中的业务逻辑
5. 生成 Model
→ goctl model mysql ddl -c -src user.sql -dir .
6. 配置 etc/*.yaml
→ 填写 DB/Redis/etcd 配置
7. 写业务代码
→ logic/ 中填充实际业务
8. 生成 Docker/K8s
→ goctl docker -go user.go
→ goctl kube deploy -name user ...常用技巧
快速生成 proto 模板
goctl rpc template -o order.proto只更新路由(不改 logic)
goctl api go -api user.api -dir .
# logic/ 文件不会被覆盖,但 routes.go 和 handler/ 会更新批量生成 Model
# DDL 文件包含多张表
goctl model mysql ddl -c -src "*.sql" -dir ./model
# 从数据库指定多张表
goctl model mysql datasource -url "..." -table "user,order,product" -c -dir ./model查看 goctl 版本
goctl --version生成 shell 补全
# Bash
goctl completion bash > /etc/bash_completion.d/goctl
# Zsh
goctl completion zsh > "${fpath[1]}/_goctl"
# PowerShell
goctl completion powershell > goctl.ps1