代码生成工具
概述
CloudWeGo 提供了强大的代码生成工具,可以根据 IDL 自动生成服务端和客户端代码,大幅提高开发效率。本章将介绍 kitex 和 hz 两个核心工具的使用方法。
核心内容
kitex 工具
kitex 是 Kitex 框架的代码生成工具,支持根据 Thrift 和 Protobuf IDL 生成代码。
安装
bash
go install github.com/cloudwego/kitex/tool/cmd/kitex@latest基本用法
bash
# 生成客户端代码
kitex -module example idl/hello.thrift
# 生成服务端代码
kitex -module example -service hello idl/hello.thrift常用参数
| 参数 | 描述 |
|---|---|
-module | Go module 名称 |
-service | 生成服务端代码,指定服务名 |
-type | 指定 IDL 类型(thrift/protobuf) |
-I | IDL 搜索路径 |
-use | 使用自定义模板 |
-gen-path | 生成代码输出路径 |
-record | 记录生成信息 |
生成目录结构
bash
kitex -module example -service hello idl/hello.thrift生成目录:
.
├── kitex_gen/ # 生成的代码
│ └── hello/
│ ├── hello.go # 类型定义
│ ├── k-consts.go # 常量
│ ├── k-hello.go # 客户端代码
│ └── helloservice/
│ ├── client.go # 客户端封装
│ ├── server.go # 服务端封装
│ └── helloservice.go # 处理器接口
├── handler.go # 服务处理器(需要实现)
├── kitex_info.yaml # 生成信息
└── main.go # 服务入口自定义模板
bash
# 使用自定义模板
kitex -module example -service hello \
-use template/custom \
idl/hello.thrift模板目录结构:
template/custom/
├── handler.go
├── main.go
└── build.shhz 工具
hz 是 Hertz 框架的代码生成工具,支持根据 IDL 生成 HTTP 服务代码。
安装
bash
go install github.com/cloudwego/hertz/cmd/hz@latest基本用法
bash
# 创建新项目
hz new -mod example -idl idl/hello.thrift
# 更新现有项目
hz update -idl idl/hello.thrift常用参数
| 参数 | 描述 |
|---|---|
-mod | Go module 名称 |
-idl | IDL 文件路径 |
-model_dir | model 目录名 |
-handler_dir | handler 目录名 |
-client_dir | client 目录名 |
-no_recurse | 不递归处理 include |
生成目录结构
bash
hz new -mod example -idl idl/hello.thrift生成目录:
.
├── biz/
│ ├── handler/ # HTTP 处理器
│ │ └── hello/
│ │ └── hello_service.go
│ ├── model/
│ │ └── hello/
│ │ └── model.go # 数据模型
│ └── router/
│ └── hello/
│ └── hello.go # 路由注册
├── idl/
│ └── hello.thrift # IDL 定义
├── main.go # 服务入口
├── router.go # 路由注册
└── go.modIDL 注解
hz 支持 Thrift 注解来定义 HTTP 路由:
thrift
namespace go hello
// 路由注解
// @route GET /hello
struct HelloRequest {
1: string name (api.query="name")
}
// @route POST /user
struct CreateUserRequest {
1: string name (api.body="name")
2: string email (api.body="email")
}
// @route GET /user/{id}
struct GetUserRequest {
1: i64 id (api.path="id")
}
service HelloService {
// @handler HelloHandler
Response Hello(1: Request req)
}thriftgo 工具
thriftgo 是 Go 实现的 Thrift 编译器,支持生成 Go 代码。
安装
bash
go install github.com/cloudwego/thriftgo@latest基本用法
bash
# 生成 Go 代码
thriftgo -r --gen go:package_prefix=example idl/hello.thrift常用参数
| 参数 | 描述 |
|---|---|
-r | 递归处理 include |
-gen | 指定生成语言和选项 |
-out | 输出目录 |
-I | IDL 搜索路径 |
代码生成示例
1. 创建项目
bash
# 创建项目目录
mkdir hello-project
cd hello-project
go mod init example
# 创建 IDL
mkdir idl
cat > idl/hello.thrift << 'EOF'
namespace go hello
struct Request {
1: string name
}
struct Response {
1: string message
}
service HelloService {
Response SayHello(1: Request req)
}
EOF2. 生成 Kitex 服务
bash
# 生成服务端代码
kitex -module example -service hello idl/hello.thrift
# 实现处理器
cat > handler.go << 'EOF'
package main
import (
"context"
"example/kitex_gen/hello"
)
type HelloHandler struct{}
func (h *HelloHandler) SayHello(ctx context.Context, req *hello.Request) (*hello.Response, error) {
return &hello.Response{
Message: "Hello, " + req.Name + "!",
}, nil
}
EOF
# 运行服务
go mod tidy
go run .3. 生成 Hertz 网关
bash
# 创建网关目录
mkdir -p gateway
cd gateway
# 使用 hz 创建项目
hz new -mod example -idl ../idl/hello.thrift
# 修改处理器调用 Kitex 服务
# 编辑 biz/handler/hello/hello_service.go
# 运行网关
go mod tidy
go run .高级配置
1. Kitex 高级选项
bash
# 高级生成选项
kitex -module example \
-service hello \
-type thrift \
-I idl/include \
-gen-path gen \
-thrift go:thrift_import_prefix=github.com/example/idl \
-thrift gen_deep_equal \
-thrift gen_setter \
idl/hello.thrift详细参数说明:
-type:指定 IDL 类型(thrift/protobuf)-I:IDL 搜索路径,用于处理 include-gen-path:生成代码的输出路径-thrift:Thrift 相关选项go:thrift_import_prefix:设置 Thrift 导入前缀gen_deep_equal:生成 DeepEqual 方法gen_setter:生成 Setter 方法gen_stringer:生成 String 方法
2. hz 高级选项
bash
# 高级生成选项
hz new \
-mod example \
-idl idl/hello.thrift \
-model_dir biz/model \
-handler_dir biz/handler \
-client_dir biz/client \
-router_dir biz/router \
-no_default_router \
-idl_type thrift \
-template=slim详细参数说明:
-model_dir:模型目录-handler_dir:处理器目录-client_dir:客户端目录-router_dir:路由目录-no_default_router:不生成默认路由-idl_type:IDL 类型-template:模板类型(slim/full)
3. 自定义插件
bash
# 使用自定义插件
kitex -module example \
-service hello \
-plugin go:gen_validator \
-plugin go:gen_mock \
idl/hello.thrift常用插件:
gen_validator:生成参数验证代码gen_mock:生成 mock 代码gen_json:生成 JSON 序列化代码gen_gorm:生成 GORM 模型代码
CI/CD 集成
1. GitHub Actions 集成
yaml
# .github/workflows/idl.yml
name: IDL Code Generation
on:
push:
paths:
- 'idl/**'
pull_request:
paths:
- 'idl/**'
jobs:
generate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Go
uses: actions/setup-go@v3
with:
go-version: '1.21'
- name: Install codegen tools
run: |
go install github.com/cloudwego/kitex/tool/cmd/kitex@latest
go install github.com/cloudwego/hertz/cmd/hz@latest
go install github.com/cloudwego/thriftgo@latest
- name: Generate Kitex code
run: |
kitex -module example -service hello idl/hello.thrift
- name: Generate Hertz code
run: |
hz new -mod example -idl idl/hello.thrift
- name: Check generated code
run: |
git status
if git diff --exit-code; then
echo "No changes to generated code"
else
echo "Generated code changed, please commit"
exit 1
fi2. GitLab CI 集成
yaml
# .gitlab-ci.yml
stages:
- generate
- test
codegen:
stage: generate
image: golang:1.21
script:
- go install github.com/cloudwego/kitex/tool/cmd/kitex@latest
- go install github.com/cloudwego/hertz/cmd/hz@latest
- kitex -module example -service hello idl/hello.thrift
- hz new -mod example -idl idl/hello.thrift
- git diff --exit-code || (
echo "Generated code changed, please commit" &&
exit 1
)
only:
changes:
- idl/**3. Jenkins 集成
groovy
// Jenkinsfile
pipeline {
agent any
stages {
stage('Generate Code') {
when {
changeset pattern: 'idl/**', comparator: 'REGEXP'
}
steps {
sh 'go install github.com/cloudwego/kitex/tool/cmd/kitex@latest'
sh 'go install github.com/cloudwego/hertz/cmd/hz@latest'
sh 'kitex -module example -service hello idl/hello.thrift'
sh 'hz new -mod example -idl idl/hello.thrift'
sh 'git diff --exit-code || exit 1'
}
}
stage('Test') {
steps {
sh 'go test ./...'
}
}
}
}4. 预提交钩子
bash
#!/bin/bash
# .git/hooks/pre-commit
# 检查 IDL 文件是否修改
if git diff --cached --name-only | grep -q "\.thrift$\|\.proto$"; then
echo "IDL files modified, regenerating code..."
# 安装工具
go install github.com/cloudwego/kitex/tool/cmd/kitex@latest
go install github.com/cloudwego/hertz/cmd/hz@latest
# 生成代码
kitex -module example -service hello idl/hello.thrift
hz new -mod example -idl idl/hello.thrift
# 提交生成的代码
git add kitex_gen/ biz/
echo "Code generated and added to commit"
fi最佳实践
1. 代码生成工作流
推荐工作流:
- 编写 IDL:定义服务接口和数据结构
- 生成代码:使用 kitex/hz 生成代码
- 实现业务逻辑:在生成的处理器中实现业务逻辑
- 测试:编写单元测试和集成测试
- CI/CD:集成到持续集成流程
2. 版本管理
版本管理最佳实践:
- 将生成的代码提交到版本控制系统
- 使用 git 标签管理 IDL 版本
- 为不同版本的 IDL 生成对应版本的代码
- 维护代码生成的配置文件
3. 性能优化
代码生成性能优化:
- 使用增量生成:只生成修改的文件
- 缓存生成结果:避免重复生成
- 并行生成:同时处理多个 IDL 文件
- 优化模板:减少模板复杂度
4. 常见问题
常见问题及解决方法:
| 问题 | 原因 | 解决方法 |
|---|---|---|
| 生成的代码编译错误 | Go 版本不兼容 | 使用 Go 1.18+ |
| 导入路径错误 | module 名称不正确 | 检查 -module 参数 |
| 模板渲染失败 | 模板语法错误 | 检查模板文件 |
| 依赖冲突 | 版本不匹配 | 运行 go mod tidy |
| 生成速度慢 | IDL 文件过大 | 拆分 IDL 文件 |
5. 工具链集成
推荐工具链:
- IDL Linter:检查 IDL 语法和规范
- 代码格式化:使用 go fmt 格式化生成的代码
- 静态分析:使用 golangci-lint 分析生成的代码
- 依赖管理:使用 go mod 管理依赖
集成示例:
bash
# 完整的工具链集成脚本
#!/bin/bash
# 1. 检查 IDL
idl-lint idl/
# 2. 生成代码
kitex -module example -service hello idl/hello.thrift
hz new -mod example -idl idl/hello.thrift
# 3. 格式化代码
go fmt ./...
# 4. 静态分析
golangci-lint run
# 5. 下载依赖
go mod tidy
# 6. 运行测试
go test ./...小结
本章介绍了 CloudWeGo 的代码生成工具及其高级用法:
核心工具:
- kitex:Kitex 框架的代码生成工具
- hz:Hertz 框架的代码生成工具
- thriftgo:Go 实现的 Thrift 编译器
高级配置:
- Kitex 高级选项:类型指定、搜索路径、生成选项
- hz 高级选项:目录配置、模板选择、路由设置
- 自定义插件:验证器、mock、JSON 序列化、GORM 模型
CI/CD 集成:
- GitHub Actions:自动化代码生成和检查
- GitLab CI:集成到 GitLab 持续集成
- Jenkins:企业级 CI/CD 集成
- 预提交钩子:本地代码生成检查
最佳实践:
- 代码生成工作流:IDL 编写、代码生成、业务实现、测试、CI/CD
- 版本管理:代码提交、版本标签、配置维护
- 性能优化:增量生成、缓存、并行处理
- 工具链集成:IDL 检查、代码格式化、静态分析
常见问题:编译错误、导入路径、模板渲染、依赖冲突、性能问题
通过本章的学习,你应该掌握了如何高效使用 CloudWeGo 的代码生成工具,从手动编码到自动化生成,大幅提高开发效率。在下一章中,我们将学习 CloudWeGo 项目的推荐目录结构,进一步规范项目组织。