跳转到内容

项目结构

goctl 为每个项目生成一致的目录结构,熟悉它是快速上手任何 go-zero 代码库的最佳途径。

goctl api go -api user.api -dir . 生成:

user-api/
├── etc/
│ └── user-api.yaml # 运行时配置(host、port、DB、RPC 地址)
├── internal/
│ ├── config/
│ │ └── config.go # 映射 YAML 的强类型结构体
│ ├── handler/
│ │ ├── routes.go # 自动生成的路由注册
│ │ └── loginhandler.go # 每个 @handler 一个文件——绑定请求、调用 logic
│ ├── logic/
│ │ └── loginlogic.go # 业务逻辑——通常只需修改此处
│ ├── svc/
│ │ └── servicecontext.go # 共享依赖:DB、RPC 客户端、Redis 等
│ └── types/
│ └── types.go # 自动生成的请求/响应结构体
└── user-api.go # main()——启动 rest.Server

goctl rpc protoc user.proto --zrpc_out=. 生成:

user-rpc/
├── etc/
│ └── user-rpc.yaml # ListenOn、Etcd 注册、DB 配置
├── internal/
│ ├── config/
│ │ └── config.go
│ ├── logic/
│ │ └── getuserlogic.go # 每个 RPC 方法一个文件
│ ├── server/
│ │ └── userserver.go # gRPC Server 实现——委托给 logic 层
│ └── svc/
│ └── servicecontext.go
├── pb/
│ └── user/ # protoc 生成的 .pb.go 与 _grpc.pb.go
├── userclient/
│ └── user.go # go-zero 生成的类型安全客户端封装
└── user.go # main()——启动 zrpc.Server
职责是否包含业务逻辑
Handlerinternal/handler解析并校验 HTTP 请求,调用 logic,写响应
Logicinternal/logic实现业务用例,编排 DB/缓存/RPC 调用
ServiceContextinternal/svc启动时初始化并持有共享依赖
Configinternal/config将 YAML 字段映射为强类型 Go 结构体
Modelinternal/model数据访问层(由 goctl model 生成)

对于包含多个服务的仓库,推荐如下约定:

project-root/
├── service/
│ ├── user/
│ │ ├── api/ # user-api
│ │ └── rpc/ # user-rpc
│ ├── order/
│ │ ├── api/
│ │ └── rpc/
│ └── payment/
│ └── rpc/
├── common/ # 公共工具(错误码、中间件等)
└── deploy/
├── docker-compose.yaml
└── k8s/
  • Handler 保持精简 — handler 只做请求解码、调用 logic、编码响应,不堆业务代码。
  • 每个用例一个 logic 文件CreateOrderLogicGetOrderLogicCancelOrderLogic 各自独立,即使方法很小。
  • ServiceContext 是唯一的构造入口 — 不要在 svc.NewServiceContext 之外调用 sql.Openredis.NewClient
  • 配置优于硬编码 — 超时时间、功能开关、下游地址等所有可调参数都放入 etc/*.yaml
  • Model 层自动生成,Logic 层归你所有 — 可以随时重新生成 model;logic 层是你的业务代码所在地,goctl 永远不会覆盖它。