Golang微服务项目如何组织代码_Golang微服务工程结构

发布时间 - 2026-02-02 00:00:00    点击率:
domain层只放纯粹的领域模型、核心规则及接口定义,如User结构体、Activate()方法、UserRegisteredEvent事件和UserRepository接口,禁止依赖外部包或含副作用操作。

微服务项目里 domain 层该放什么

domain 层不是“业务逻辑大杂烩”,而是纯粹的领域模型与核心规则。它不能依赖 infra、handler 或任何外部包,连 logtime 这类标准库之外的导入都要警惕。

常见错误是把数据库实体(如 UserModel)和领域对象(如 User)混在一起,或在 domain 里直接调用 redis.Client。正确做法是只定义接口(如 UserRepository),具体实现交给 infra 层。

  • User 结构体只含字段和方法(如 Activate()),不涉及序列化、存储、HTTP 状态
  • 领域事件(如 UserRegisteredEvent)定义在此,但不触发、不发布
  • 所有方法必须是纯函数式或仅操作自身状态,禁止副作用

internal 目录下 handler 和 service 怎么划界

handler 只做三件事:解析请求(c.Param / c.ShouldBindJSON)、调用 service、构造响应(c.JSON)。它不该有 if 判断业务分支,也不该拼接 SQL 或组装 DTO。

service 是协调者,负责编排 domain 对象、调用多个 repository、处理事务边界。它可返回 error,但绝不返回 http.StatusXxx —— 那是 handler 的责任。

  • handler 中不要出现 if user.Status == "inactive" 这类业务判断,应交由 service 返回明确 error(如 ErrUserInactive
  • service 方法名建议用动词+名词,如 TransferMoney()CancelOrder(),而非 DoSomething()
  • 避免在 service 里 new repository 实例;通过构造函数注入,便于单元测试 mock

pkg 和 internal 的分工陷阱

pkg 放可复用、无项目上下文的通用能力,比如 pkg/trace(OpenTelemetry 封装)、pkg/validator(自定义校验规则)。它必须能被其他项目 go get 直接引用。

internal 是项目私有层,包括 internal/handlerinternal/serviceinternal/infra —— 它们互相引用没问题,但外部模块无法 import internal/xxx,这是 Go 编译器强制的隔离机制。

  • 别把 internal/infra/mysql 里的 NewDB() 拆到 pkg/db,除非你真打算开源这个 MySQL 初始化逻辑
  • pkg/util 里禁止出现 config.Load()cache.Get("user:"),那已绑定项目环境
  • 如果某个 “工具函数” 需要读取 app.Config,它就该在 internal 下,而不是 pkg

go.mod 和 main.go 放哪才不踩包循环引用

微服务通常只有一个 cmd/{service-name}/main.go,它负责初始化配置、注册 infra 组件、构建 service 实例、启动 HTTP/gRPC server。所有依赖注入都在这里完成。

go.mod 必须位于项目根目录,且 module 名不能带 /cmd/internal 后缀(如 github.com/your/project),否则 go list -m all 会混乱,CI 构建时 vendor 或 go install 可能失败。

  • 绝对禁止在 internal/service 里 import cmd/xxx —— 这会立刻触发循环引用编译错误
  • 配置结构体(如 type Config struct { DB *DBConfig })建议放在 internal/config,由 cmd 层解析后传入各组件
  • 如果用了 Wire 生成依赖注入代码,wire.go 必须和 main.go 在同一目录,且 //go:build wireinject 注释不可少

最易被忽略的是测试时的包可见性:写集成测试想 moc

k infra/mysql,结果发现它被 internal/service 直接 new 出来 —— 这说明初始化逻辑没收口到 cmd 层,重构成本会陡增。


# mysql  # redis  # js  # git  # json  # go  # github  # golang  # app  # 工具  # ai  # 编译错误  # 标准库  # sql  # if  # 封装  # 构造函数  # Error  # 结构体  # 循环  # 接口  # internal  # Struct  # 对象  # 事件  # 数据库  # http  # 重构  # 这类  # 的是  # 这是  # 放在  # 都在  # 那是  # 都要  # 多个  # 在此  # 用了 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: 北京网站制作的公司有哪些,北京白云观官方网站?  网站图片在线制作软件,怎么在图片上做链接?  php做exe能调用系统命令吗_执行cmd指令实现方式【详解】  JavaScript如何实现倒计时_时间函数如何精确控制  如何登录建站主机?访问步骤全解析  简单实现Android文件上传  如何在香港免费服务器上快速搭建网站?  Laravel如何集成Inertia.js与Vue/React?(安装配置)  Laravel如何使用API Resources格式化JSON响应_Laravel数据资源封装与格式化输出  PHP怎么接收前端传的文件路径_处理文件路径参数接收方法【汇总】  如何获取PHP WAP自助建站系统源码?  Laravel怎么处理异常_Laravel自定义异常处理与错误页面教程  Bootstrap整体框架之JavaScript插件架构  Laravel中间件如何使用_Laravel自定义中间件实现权限控制  Laravel如何实现数据库事务?(DB Facade示例)  Laravel如何实现多级无限分类_Laravel递归模型关联与树状数据输出【方法】  如何彻底卸载建站之星软件?  大同网页,大同瑞慈医院官网?  昵图网官网入口 昵图网素材平台官方入口  手机网站制作平台,手机靓号代理商怎么制作属于自己的手机靓号网站?  如何用低价快速搭建高质量网站?  Laravel Livewire是什么_使用Laravel Livewire构建动态前端界面  Laravel Telescope怎么调试_使用Laravel Telescope进行应用监控与调试  Laravel如何记录日志_Laravel Logging系统配置与自定义日志通道  jQuery 常见小例汇总  高端网站建设与定制开发一站式解决方案 中企动力  进行网站优化必须要坚持的四大原则  Laravel PHP版本要求一览_Laravel各版本环境要求对照  Windows11怎样设置电源计划_Windows11电源计划调整攻略【指南】  Windows10电脑怎么设置虚拟光驱_Win10右键装载ISO镜像文件  在centOS 7安装mysql 5.7的详细教程  JavaScript如何实现继承_有哪些常用方法  高防网站服务器:DDoS防御与BGP线路的AI智能防护方案  HTML5建模怎么导出为FBX格式_FBX格式兼容性及导出步骤【指南】  iOS验证手机号的正则表达式  Laravel怎么实现模型属性转换Casting_Laravel自动将JSON字段转为数组【技巧】  个人摄影网站制作流程,摄影爱好者都去什么网站?  Laravel如何生成和使用数据填充?(Seeder和Factory示例)  b2c电商网站制作流程,b2c水平综合的电商平台?  Win11怎么开启自动HDR画质_Windows11显示设置HDR选项  ,在苏州找工作,上哪个网站比较好?  php读取心率传感器数据怎么弄_php获取max30100的心率值【指南】  Laravel怎么实现一对多关联查询_Laravel Eloquent模型关系定义与预加载【实战】  Laravel如何从数据库删除数据_Laravel destroy和delete方法区别  如何在阿里云购买域名并搭建网站?  如何在建站宝盒中设置产品搜索功能?  Laravel如何实现全文搜索功能?(Scout和Algolia示例)  香港服务器网站推广:SEO优化与外贸独立站搭建策略  php后缀怎么变mp4格式错误_修改扩展名提示格式不对怎么办【技巧】  如何打造高效商业网站?建站目的决定转化率