Skip to content
Go
goctl 代码生成

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 user

rpc 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.proto

model 子命令:数据库模型

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