echo项目一加中间件就破clean架构,因echo.context强绑定http细节,泄露至usecase/domain层;合规做法是业务逻辑只收原始值、返回领域对象,http层负责解析与适配。

为什么Echo项目一加中间件就破 Clean 架构?
因为 echo.Context 是框架强绑定类型,一旦在 usecase 或 domain 层出现,就等于把 HTTP 请求生命周期、路由参数、响应写入等细节泄露进业务核心。很多团队在封装 GetUserByID 用例时,直接传入 c echo.Context,结果导致测试必须构造完整上下文、无法脱离 Echo 运行。
真正合规的做法是:所有业务逻辑入口只接收原始值(如 id string),返回明确的领域对象或错误;HTTP 层负责从 c.Param("id")、c.QueryParam("page") 中提取、校验、转换,再喂给用例。
- 禁止在
usecase目录下 importgithub.com/labstack/echo/v4 -
data层的 repository 实现可依赖 Echo 日志器(如echo.Logger),但仅限作为Logger接口注入,不使用其任何 HTTP 相关方法 - 若需请求元信息(如用户 IP、trace ID),应通过
context.Context(标准库)传递,而非echo.Context
如何组织 internal/cmd/data/usecase/domain 目录才不踩 Go 模块陷阱?
Go 的 import 路径和 go.mod 声明必须严格一致,否则 internal 包会被外部误引用,或 domain 被 data 反向依赖。常见错误是把 data 放在 internal 外层,导致它能 import usecase —— 这直接违反 Clean 架构单向依赖规则。
正确结构只有一种:cmd → internal/app(初始化依赖树)→ internal/usecase → internal/domain → internal/data,其中 internal/data 是唯一允许 import github.com/labstack/echo/v4 的地方,且仅用于适配器实现(如 echoHTTPClient)。
Echo框架 5.1.0 版本源码包下载,适合关注 RealIP 行为变化、StartConfig.Listener、NewDefaultFS 和观测性中间件入口的开发团队。
-
cmd/main.go只做三件事:初始化配置、构建依赖容器、调用app.Run() -
internal/app不放业务逻辑,只定义依赖注入函数(如NewUserHandler(echo.Echo, usecase.GetUserUsecase)) - 所有
data实现必须通过接口注入,例如userRepo userdomain.UserRepository,接口定义在domain层
用 Echo 写 REST API 时,怎么让 DTO 和 domain 实体彻底隔离?
DTO(Data Transfer Object)是 HTTP 层专属概念,比如 CreateUserRequest 含有 PasswordConfirm 字段,而 domain 实体 User 绝对不能有该字段。混淆二者最典型的后果是:前端传错字段,后端直接 panic;或 domain 层开始处理加密逻辑,污染了业务规则。
推荐做法是,在 presentation(或 internal/presentation)目录下定义所有 DTO,并用 echo.Bind() 或手动解析(更可控)完成转换。转换逻辑不可复用、不可测试——它本就是临时胶水代码,应放在 handler 函数内或紧邻 handler 的 adapter 文件里。
- 禁止在
domain或usecase中出现json:、form:等 struct tag - DTO 字段名可含
snake_case,domain 实体必须用CamelCase,强制视觉隔离 - 用
mapstructure.Decode或手写转换函数,避免用reflect类通用映射库,防止隐式字段穿透
日志、错误、认证中间件怎么塞进 Clean 架构又不污染业务?
中间件本质是外层切面,但很多人把它写成“业务增强”:在 auth 中间件里调用 userUsecase.GetByToken(),这会让认证逻辑和用例耦合,后续换 JWT 为 Session 就得改业务层。
干净的做法是:中间件只做三件事——提取、验证、注入。提取 token,验证格式与签名,将解析出的 userID 和 roles 注入到 context.Context;业务用例通过参数或依赖注入拿到 auth.UserContext 接口,具体实现由 data 层提供,与中间件完全解耦。
- 认证中间件不 import 任何
usecase或domain,只依赖crypto、jwt等基础库 - 日志中间件记录耗时、状态码、路径即可,不记录请求体或响应体(隐私与性能)
- 错误中间件统一处理
usecase.ErrNotFound、usecase.ErrInvalidInput等自定义错误,转成对应 HTTP 状态码,不透出 stack trace
domain 和 usecase 的纯度——只要某处用了 echo.Context 或 http.Request,整条依赖链就已失守。每次提交前,用 grep -r "echo.Context" internal/ | grep -v "presentation\|adapter" 扫一遍,比画架构图管用得多。










