Kratos项目标准目录结构必须包含/cmd、/internal、/pkg三个核心目录:/cmd仅存main入口,每个子目录对应一个可执行文件;/internal按biz/data/service三层物理隔离,单向依赖;/pkg为对外可go get的稳定公共库,非必要不放。

kratos项目标准目录结构怎么定
Kratos项目不是靠“自由发挥”组织的,而是有明确层级约束和语义分工。根目录下必须出现 /cmd、/internal、/pkg 三个核心目录,缺一不可——这是 Go 编译器强制识别 internal 包可见性的前提,也是 Kratos 工具链(如 kratos run、make api)能正常工作的基础。
-
/cmd下每个子目录名对应一个可执行文件名,例如/cmd/demo最终生成demo二进制;该目录只放main.go和极少量启动逻辑,业务代码严禁写进去 -
/internal是真正的业务代码主场,按职责再分:/internal/biz(领域逻辑)、/internal/data(数据访问)、/internal/service(服务编排),三者之间只能单向依赖(biz → data,service → biz) -
/pkg不是“工具包集合”,而是**对外暴露的、可被其他项目直接 import 的公共库**;比如你封装了一个通用的 Redis 封装或配置加载器,且确定会被其他团队复用,才放这里;否则一律进/internal/pkg
为什么不能把所有代码塞进 /internal/app
初学者常把整个应用代码堆在 /internal/app/myapp 下,看似整洁,实则破坏了 Kratos 的分层契约。一旦业务变复杂,app 目录会迅速膨胀成“上帝包”,导致:
- 无法被
ent或wire等工具正确识别依赖边界,自动生成代码失败 - 单元测试难以 mock
data层,因为biz和data混在同一包里,Go 的包级可见性机制失效 - 后续拆微服务时,
service层无法独立打包为 RPC 接口,因为没有清晰的接口定义出口
正确的做法是:哪怕单体应用,也严格维持 biz、data、service 三层物理隔离。它们可以同属一个模块(如 /internal/user),但必须是三个独立子目录。
api/ 和 internal/service/ 的关系怎么理清
/api 目录只放 .proto 文件,它不是“接口实现”,而是**协议契约**;/internal/service 才是真正实现这些接口的地方。两者通过 make api 命令桥接:
-
api/user/v1/user.proto定义GetUser方法 →make api生成api/user/v1/user_http.pb.go和api/user/v1/user_grpc.pb.go -
internal/service/user_service.go实现UserProvider.Get方法,被 HTTP/GRPC 生成代码调用 - 关键点:
service层不 importapi包,而是通过接口抽象解耦(如user.Service接口定义在/internal/biz/user)
如果在 service 里直接引用 api.UserRequest,说明分层已破,后续切换传输协议(比如从 gRPC 改 HTTP JSON)会牵一发而动全身。
internal/pkg 和 pkg 的使用边界在哪
这个最容易混淆。简单记:
-
/internal/pkg是“项目内私有工具集”,比如你写了个通用的 JWT 解析器,只给本项目多个service用,就放这里;它不能被外部项目 import,Go 编译器会报错 -
/pkg是“可发布 SDK”,比如你把日志封装、熔断器、配置中心适配器整理成独立模块,并准备推送到公司内部 Git 仓库供其他项目go get,才放这里 - 实际项目中,90% 的“工具代码”应落在
/internal/pkg;过早往/pkg放,反而增加维护负担和版本兼容风险
目录结构不是为了好看,而是为了让 wire 能注入、ent 能扫描、make api 能生成、团队成员一眼看懂代码归属。一旦开始妥协“先放一起,以后再拆”,基本就回不去了。


















