返回顶部
g

go-architectGo架构工具

Go application architecture with net/http 1.22+ routing, project structure patterns, graceful shutdown, and dependency injection. Use when building Go web servers, designing project layout, or structuring application dependencies.

作者: admin | 来源: ClawHub
源自
ClawHub
版本
V 2.3.0
安全检测
已通过
111
下载量
免费
免费
0
收藏
概述
安装方式
版本历史

go-architect

首席Go架构师

快速参考

主题参考
扁平与模块化项目布局、迁移信号references/project-structure.md
带信号处理的优雅关闭
references/graceful-shutdown.md | | 依赖注入模式、测试接缝 | references/dependency-injection.md |

核心原则

  1. 1. 标准库优先 -- 使用 net/http 和 Go 1.22+ 增强版 ServeMux 进行路由。只有在标准库无法满足具体需求时才使用框架(chi、echo、gin),例如复杂中间件链、正则路由。
  2. 依赖注入优于全局变量 -- 通过结构体字段和构造函数传递数据库、日志记录器和服务,绝不使用包级 var。
  3. 显式优于魔法 -- 不使用 init() 副作用,不进行框架自动装配。main.go 是组合根,所有内容在此显式组装。
  4. 小接口,大结构体 -- 在使用方定义接口,保持接口精简(1-3个方法)。具体类型承载实现。

Go 1.22+ 增强路由

Go 1.22 升级了 http.ServeMux,支持基于方法的路由和路径参数,消除了使用第三方路由器的最常见原因。

基于方法的路由和路径参数

go
mux := http.NewServeMux()
mux.HandleFunc(GET /api/users, s.handleListUsers)
mux.HandleFunc(GET /api/users/{id}, s.handleGetUser)
mux.HandleFunc(POST /api/users, s.handleCreateUser)
mux.HandleFunc(DELETE /api/users/{id}, s.handleDeleteUser)

提取路径参数

go
func (s Server) handleGetUser(w http.ResponseWriter, r http.Request) {
id := r.PathValue(id)
if id == {
http.Error(w, 缺少id, http.StatusBadRequest)
return
}

user, err := s.users.GetUser(r.Context(), id)
if err != nil {
s.logger.Error(获取用户, err, err, id, id)
http.Error(w, 内部错误, http.StatusInternalServerError)
return
}

w.Header().Set(Content-Type, application/json)
json.NewEncoder(w).Encode(user)
}

通配符和精确匹配

go
// 尾随斜杠的精确匹配 -- 仅服务于 /api/files/
mux.HandleFunc(GET /api/files/, s.handleListFiles)

// 通配符匹配到路径末尾 -- /api/files/path/to/doc.txt
mux.HandleFunc(GET /api/files/{path...}, s.handleGetFile)

路由优先级

新的 ServeMux 使用最具体优先的规则:

  • - GET /api/users/{id} 比 GET /api/users/ 更具体
  • GET /api/users/me 比 GET /api/users/{id} 更具体
  • 带方法的路由优先于不带方法的路由

服务器结构体模式

Server 结构体是应用程序的中央依赖容器。它持有所有共享依赖并实现 http.Handler。

go
type Server struct {
db *sql.DB
logger *slog.Logger
router *http.ServeMux
}

func NewServer(db sql.DB, logger slog.Logger) *Server {
s := &Server{
db: db,
logger: logger,
router: http.NewServeMux(),
}
s.routes()
return s
}

func (s *Server) routes() {
s.router.HandleFunc(GET /api/users/{id}, s.handleGetUser)
s.router.HandleFunc(POST /api/users, s.handleCreateUser)
s.router.HandleFunc(GET /healthz, s.handleHealth)
}

func (s Server) ServeHTTP(w http.ResponseWriter, r http.Request) {
s.router.ServeHTTP(w, r)
}

中间件包装

在 http.Server 级别或按路由应用中间件:

go
// 包装整个服务器
httpServer := &http.Server{
Addr: :8080,
Handler: requestLogger(s),
}

// 或按路由
s.router.Handle(GET /api/admin/, adminOnly(http.HandlerFunc(s.handleAdmin)))

中间件签名

go
func requestLogger(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
next.ServeHTTP(w, r)
slog.Info(请求, method, r.Method, path, r.URL.Path, dur, time.Since(start))
})
}

项目结构

根据项目规模选择:

从扁平结构开始。当看到参考文档中描述的迹象时进行迁移。

优雅关闭

每个生产级Go服务器都需要优雅关闭。该模式使用 signal.NotifyContext 监听操作系统信号,使用 http.Server.Shutdown 排空连接。

go
ctx, cancel := signal.NotifyContext(ctx, os.Interrupt, syscall.SIGTERM)
defer cancel()

// ... 在goroutine中启动服务器 ...

<-ctx.Done()

shutdownCtx, shutdownCancel := context.WithTimeout(context.Background(), 10*time.Second)
defer shutdownCancel()
httpServer.Shutdown(shutdownCtx)

完整的清理顺序模式见 references/graceful-shutdown.md

何时加载参考文档

加载 project-structure.md 时:

  • - 搭建新的Go项目
  • 讨论包布局或目录组织
  • 项目正在增长需要重构

加载 graceful-shutdown.md 时:

  • - 设置生产级HTTP服务器
  • 实现信号处理或干净关闭
  • 讨论部署或容器就绪性

加载 dependency-injection.md 时:

  • - 设计服务、存储和处理器如何连接
  • 使用接口使代码可测试
  • 审查构造函数或装配逻辑

反模式

全局数据库变量

go
// 错误 -- 不可测试,隐藏依赖
var db *sql.DB

func handleGetUser(w http.ResponseWriter, r *http.Request) {
db.QueryRow(...)
}

通过Server或Service结构体传递 db。

框架优先思维

不要以 gin.Default() 或 echo.New() 开始。以 http.NewServeMux() 开始。只有在遇到标准库的真正限制时才引入框架。

上帝包

一个包含50个文件的 handlers 包不是组织。按领域分组(user、order、billing),而不是按技术层。

使用init()进行设置

go
// 错误 -- 不可见的副作用,不可测试
func init() {
db, = sql.Open(postgres, os.Getenv(DATABASEURL))
}

所有初始化属于 main() 或 run() 函数,以便可以测试并处理错误。

在业务逻辑中读取配置

go
// 错误 -- 将处理器耦合到环境
func (s Server) handleSendEmail(w http.ResponseWriter, r http.Request) {
apiKey := os.Getenv(SENDGRIDAPIKEY) // 不要这样做
}

通过构造函数注入配置值或客户端。

标签

skill ai

通过对话安装

该技能支持在以下平台通过对话安装:

OpenClaw WorkBuddy QClaw Kimi Claude

方式一:安装 SkillHub 和技能

帮我安装 SkillHub 和 go-architect-1776097450 技能

方式二:设置 SkillHub 为优先技能安装源

设置 SkillHub 为我的优先技能安装源,然后帮我安装 go-architect-1776097450 技能

通过命令行安装

skillhub install go-architect-1776097450

下载

⬇ 下载 go-architect v2.3.0(免费)

文件大小: 14.15 KB | 发布时间: 2026-4-14 14:26

v2.3.0 最新 2026-4-14 14:26
- Added Go 1.22+ `net/http` routing guidance, including method-based routes and path parameters.
- Expanded best practices on project structure, dependency injection, and graceful shutdown, with quick-reference links to detailed guides.
- Provided example code for routing, middleware, server struct patterns, and graceful shutdown handling.
- Updated anti-patterns section with clear advice and code samples to avoid common mistakes.
- Refined recommendations for when to use standard library vs. frameworks and when to use supporting reference material.

Archiver·手机版·闲社网·闲社论坛·羊毛社区· 多链控股集团有限公司 · 苏ICP备2025199260号-1

Powered by Discuz! X5.0   © 2024-2025 闲社网·线报更新论坛·羊毛分享社区·http://xianshe.com

p2p_official_large
返回顶部