lab/note/资源/编程/Golang/go-zero/goctl.md
张育新 be711334fb docs(note): 添加笔记目录及 gitignore 规则
- 新增 note 目录包含 AI、SQL、Golang、网络等多领域学习笔记
- 更新 .gitignore 添加 note/assets/ 和 note/项目/ 忽略规则
2026-07-10 09:24:40 +08:00

124 lines
4.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

## API
### goctl代码生成
可以在doc/genCode.md查看
```powershell
# 生成多个types类型的话需要关闭这个实验性功能
goctl env -w GOCTL_EXPERIMENTAL=off
# 代码生成会自动处理引入的子api文件
goctl api go -api background.api -dir . --home D:/zhangyuxin/template/1.8.3
goctl api go -api login.api -dir . --home ../../../deploy/goctl
goctl api go -api main.api -dir . --home ../../deploy/goctl
```
### 参数校验
| 接收规则 | 说明 | 示例 |
| -------- | ------------------------------------------ | ------------------------------- |
| optional | 当前字段是可选参数,允许为零值(zero value) | `json:"foo,optional"` |
| options | 当前参数仅可接收的枚举值 | `json:"gender,options=foo|bar"` |
| default | 当前参数默认值 | `json:"gender,default=male"` |
| range | 当前参数数值有效范围,支持开/闭区间 | `json:"age,range=[0:120]"` |
#### **`optional`** **与** **`omitempty`** **的区别**
两者都写在 json/form tag 的 options 里,但作用域完全不同,不可互相替代
##### `optional` —— goctl 专用,控制 Swagger 与请求校验
- **Swagger 生成**:标了 `optional` 的字段不进 `required` 数组Apifox/Swagger UI 显示为可选;未标的字段进 `required` 数组,显示为必填
- **请求校验**goctl 生成的 logic 不会对标了 `optional` 的字段做必填校验
- **判定逻辑**goctl 遍历 tag options找到 `optional` 关键字即判定为可选
##### `omitempty` —— Go 标准库指令,控制 JSON 序列化
- **JSON 序列化**字段为零值0、""、nil、false响应 JSON 中**不输出**该字段
- **Swagger 生成****goctl 完全不识别**,字段仍按未标 `optional` 处理,即判定为 required
- **请求校验**:无影响
## RPC
### goctl代码生成
```powershell
# 主proto文件代码生成
goctl rpc protoc user.proto --go_out=. --go-grpc_out=. --zrpc_out=. --proto_path=. -m --home ../../../deploy/goctl
# 主proto文件中引入的proto代码生成
protoc.exe -I ./ --go_out=. --go-grpc_out=. ./user_model.proto
```
当`proto`文件里面定义了多个 service的时候需要额外注意还要再main函数中手动注册一下
> 每个 proto 文件应该聚焦于一个核心概念/实体。一个文件里定义太多 service 通常是设计需要重新考虑的信号
注册示例
```go
import (
ebookServer "olive/services/product/rpc/internal/server/ebookservice"
)
var configFile = flag.String("f", "etc/product.yaml", "the config file")
func main() {
flag.Parse()
var c config.Config
conf.MustLoad(*configFile, &c)
ctx := svc.NewServiceContext(c)
s := zrpc.MustNewServer(c.RpcServerConf, func(grpcServer *grpc.Server) {
// 新服务
productrpcmodel.RegisterEbookServiceServer(grpcServer, ebookServer.NewEbookServiceServer(ctx))
})
defer s.Stop()
fmt.Printf("Starting product RPC server at %s...\n", c.ListenOn)
s.Start()
}
```
### proto代码生成错误File not found错误
- 错误描述
执行 protoc 报 google/protobuf/timestamp.proto: File not found. 的错提示File not found
- 解决方式
重新下载[protoc](https://github.com/protocolbuffers/protobuf/releases)解压后将整个include目录复制到protoc执行文件同一级目录下
## model
可以在doc/genCode.md查看
**Model 层**:只做 **“业务循环”** + **“SQL 查询”** + **“结果封装”**,不关心字符串到时间的转换和 Protobuf 类型。
### goctl代码生成
```powershell
# mysql根据远程数据库表生成
goctl model mysql datasource --url="olive:xxvkikaDDx01&&99@tcp(127.0.0.1:3306)/ebming" --table="user_invitation_record" --dir="." -c --home ../../../../deploy/goctl/1.8.3
# mysql根据ddl生成
goctl model mysql ddl --src h5.sql --dir . -c --home D:/zhangyuxin/template/1.8.3
# pgsql根据远程数据库表生成
goctl model pg datasource -url "postgres://labman:tN5bWz2KpL9Fy4@127.0.0.1:15432/sern" -table user -dir ./user --cache --home ../../goctl_template/1.8.3
# pgsql根据远程数据库表生成,带模式schema
goctl model pg datasource -url "postgres://admin:zhangyuxin@127.0.0.1:25432/test?sslmode=disable" -s "users" -table "profile" -dir ./go-zero/model/users/ --cache --home ../../deploy/goctl
```