# GoOmni GoOmni 是一套面向业务复用的 Go 后端基础框架。当前默认用 Gin 作为网络适配器,业务代码只依赖 GoOmni 的 transport-neutral API,后续可以替换为自研网络层。 远程 module 地址是 `git.yuntuo.hk/k2safe/go-omni`。业务项目可以直接引用指定版本: ```sh go get git.yuntuo.hk/k2safe/go-omni@v0.3.1 ``` 创建新业务项目: ```sh go install git.yuntuo.hk/k2safe/go-omni/cmd/go-omni@v0.3.1 go-omni new --module example.com/billing ./billing cd billing go mod tidy go run ./cmd/server ``` 远程安装的 CLI 默认引用自身版本,生成的项目不需要本地 `replace`。 具体版本和本地开发选项见 [CLI 文档](cmd/go-omni/README.md)。 需要数据库持久化时,使用 `go-omni new --database mysql --module example.com/billing ./billing`。 生成项目包含完整用户 CRUD、数据库 Repository、ServiceContext、建表脚本和就绪探针。 先应用生成的 `schema.sql`,再配置 `GO_OMNI_DB_DSN`;启动时会检查连接与表结构,退出时释放连接池。 ## 目录结构 ```text go-omni/ ├── app/ # 应用启动和生命周期 ├── httpx/ # 与网络框架无关的 HTTP 抽象 ├── response/ # 统一响应 ├── errors/ # 统一错误 ├── health/ # 存活和就绪检查 ├── middleware/ # 请求 ID 等基础中间件 ├── logx/ # 业务层结构化日志 ├── config/ # 配置管理 ├── validate/ # 参数校验 ├── auth/ # 认证和权限接口 ├── database/ # database/sql 生命周期和事务 ├── transport/gin/ # Gin 网络适配器,可替换 ├── examples/ # 示例项目 └── cmd/ # go-omni 项目脚手架 ``` ## 快速开始 ```go package main import omni "git.yuntuo.hk/k2safe/go-omni" func main() { app := omni.New() app.GET("/health", func(ctx *omni.Context) error { return ctx.OK(map[string]string{"status": "ok"}) }) app.Run(":8080") } ``` 成功响应默认使用统一结构: ```json { "code": "OK", "message": "success", "data": {"status": "ok"}, "requestId": "..." } ``` 业务错误可以直接返回: ```go return omni.NotFound("USER_NOT_FOUND", "user was not found") ``` 默认 Gin 适配器位于 `transport/gin`。业务层不需要导入 Gin;如果后续实现自己的网络层,只需要实现 `httpx.Router` / `httpx.RouterGroup`,然后通过 `omni.NewWithRouter` 启动应用: ```go application := omni.NewWithRouter(myRouter) ``` 仓库还提供了使用标准库路由的 `transport/nethttp` 参考实现。两种适配器已通过同一套路由、业务处理链和取消传播测试,完整用户 CRUD 复用同一份 Handler / Service。 自研适配器可以直接运行 `transport/transporttest.Run` 验收。具体规则、v0.3.1 的斜杠 / Any / 405 行为调整,以及自研网络内核与当前 HTTP 接口的边界,见 [适配层契约](transport/README.md)。 `app.Engine()` 现在返回标准 `http.Handler`,`ctx.Raw()` 返回适配器提供的 `http.ResponseWriter`,避免业务 API 锁定 Gin 类型。 业务代码可以直接使用 `git.yuntuo.hk/k2safe/go-omni/logx` 打结构化日志,不需要依赖 Gin: ```go func (s *UserService) Create(ctx *httpx.Context) error { logx.InfoContext(ctx.Context(), "user.create", "email", input.Email) return nil } ``` `WithLogger(true)` 会启用 GoOmni 的统一 HTTP 访问日志;日志内容和业务日志共用 `requestId`。应用启动时可以调用 `logx.Setup` 配置 JSON/文本格式、级别、服务名和输出文件。 应用配置可以统一从 `GO_OMNI_*` 环境变量加载,再交给 `omni.New`: ```go settings, err := omni.LoadConfig("") if err != nil { log.Fatal(err) } logger, err := logx.New(settings.Log) if err != nil { log.Fatal(err) } application := omni.New(omni.WithConfig(settings)) application.OnShutdown(logger.Close) ``` 常用变量包括 `GO_OMNI_ENABLE_LOGGER`、`GO_OMNI_LOG_LEVEL`、 `GO_OMNI_LOG_FORMAT`、`GO_OMNI_LOG_OUTPUT`、`GO_OMNI_SERVICE`、 `GO_OMNI_ENVIRONMENT`、`GO_OMNI_HTTP_ADDR` 和 `GO_OMNI_SHUTDOWN_TIMEOUT`。数据库连接仍由 `database.ConfigFromEnv` 从 `GO_OMNI_DB_*` 加载。 `App` 同时实现标准 `http.Handler`。`Run` 监听 `SIGINT` / `SIGTERM`;`RunContext` 则由调用方的 context 控制退出,生成项目已使用 `signal.NotifyContext` 接好信号。 退出时先停止接收新请求,等待活跃请求完成,再执行资源清理。超过 `ShutdownTimeout` 时强制关闭连接、取消请求 context,并返回超时错误。业务代码应响应 context 取消;框架无法强制结束忽略取消的业务 goroutine。数据库连接池由 `database.Open` 创建,在服务退出时调用 `Close`。 应用资源可以直接挂到 `omni.New` 返回的生命周期上: ```go application := omni.New() application.OnShutdown(db.Close) ``` 清理函数会按注册顺序的逆序执行,`application.Close()` 和 `RunContext` 都会触发,且重复调用安全。 服务可以把数据库、缓存等依赖注册为就绪探针: ```go checker, err := health.New(health.Probe{ Name: "database", Check: db.PingContext, }) if err != nil { log.Fatal(err) } application.GET("/health/live", checker.LivenessHandler()) application.GET("/health/ready", checker.ReadinessHandler()) ``` 存活检查只确认进程在线;就绪检查会执行全部探针,任意依赖失败时返回 HTTP 503。 新项目脚手架会生成项目自己的 `internal/servicecontext`。它集中保存 Logger、数据库、缓存和外部客户端,Service 只依赖这个项目上下文,不把基础设施初始化散落到各个 Handler: ```go services, err := servicecontext.New(ctx, logger) if err != nil { return err } defer services.Close() userService := service.NewUsers(services) ``` ## 完整业务参考项目 [`examples/reference`](examples/reference/README.md) 提供按 Handler / Service / Repository / Model 分层的用户 CRUD 示例。默认使用并发安全的内存存储,支持分页、邮箱唯一校验、结构化请求日志和统一错误,无需配置数据库。 从远程版本生成并升级一个独立业务模块,可运行: ```sh python3 scripts/verifyBusiness.py --version v0.3.1 ``` 该验收会在临时目录中先固定 `v0.2.0`,再升级到 `v0.3.1`,检查无本地 replace、配置加载、结构化日志、requestId、CRUD、校验错误、业务错误和优雅退出。 在框架根目录运行: ```sh go run ./examples/reference ``` 默认地址为 `http://127.0.0.1:8080`。示例文档提供完整的 curl 操作流程。数据只保存在内存中,重启后清空。 框架的 `App` 也实现了标准 `http.Handler`,可以直接用于 `http.Server` 和 `httptest.NewServer`;业务路由可通过 `*omni.RouterGroup` 注册,无需导入 Gin。 ## 当前边界 缓存、消息队列和定时任务暂时作为后续可选模块。认证层只定义 `Authenticator`、`Principal` 和路由保护中间件,具体 JWT、Session 或 OAuth 由项目实现。核心数据库层只依赖 `database/sql`,具体驱动、迁移和表结构由项目选择。 当前成熟度与后续验收标准见 [ROADMAP.md](ROADMAP.md),版本变更见 [CHANGELOG.md](CHANGELOG.md)。