Files
go-common/INTEGRATION.md

7.4 KiB
Raw Permalink Blame History

GoCommon 业务项目对接手册

模块路径:git.toowon.com/jimmy/go-common

目标架构一步到位,不考虑向后兼容。


1. 原则

原则 说明
Factory 只是入口 启动初始化一次getter 取模块对象
能力在模块自身 log.Info()db.Find()store.Upload(),不在 Factory 透传
按需配置 只用到的模块写进 config.json
不重写基础设施 连接池、HTTP 出参、中间件链由本库提供
业务只管业务 Service 返回数据;出参用 http.Handler;迁移只写 SQL

登录鉴权、参数校验、出站 HTTP Client 等由业务项目自行实现,不在本库范围。


2. 安装

go env -w GOPRIVATE=git.toowon.com
go env -w GONOPROXY=git.toowon.com
go env -w GONOSUMDB=git.toowon.com
git config --global url."git@git.toowon.com:".insteadOf "https://git.toowon.com/"

go get git.toowon.com/jimmy/go-common@v1.2.0

配置示例:config/example.json


3. 推荐结构

your-project/
├── config.json
├── cmd/server/main.go      # 复制 templates/server/main.go
├── cmd/migrate/main.go     # 复制 templates/migrate/main.go
├── migrations/
├── locales/                # 可选
├── internal/handler/
├── internal/service/
└── go.mod

4. 启动(只做一次)

cp templates/server/main.go cmd/server/main.go

模板默认已包含:MustInit + buildOptionsOption 挂载点)+ MustLogger + Warmup + MiddlewareChain + NewHandler + Close

复制后主要改三处:

函数 用途
buildOptions() WithLogger / WithStorage 等自定义注入
setupMiddleware() chain.Append(业务鉴权…)
registerRoutes() 注册业务路由
go run ./cmd/server -config config.json -addr :8080

5. 获取模块对象

连接由 Factory lazy 缓存。业务侧不要自行 gorm.Open / redis.NewClient

模块 API 说明
配置 Config() 原始配置
数据库 Database() / MustDatabase() *gorm.DB
Redis Redis() / MustRedis() *redis.Client
日志 Logger() / MustLogger() 退出用 Close()
存储 Storage() / MustStorage() Upload / GetURL
邮件 Email() / MustEmail() SendEmail / SendEmailAsync
短信 SMS() / MustSMS() SendSMS / SendSMSAsync
Excel Excel() 每次新建导出器
国际化 I18n() / MustI18n() 一般由 NewHandler 注入
MCP 工具 MCP() / MustMCP() ListTools / CallTool(见 §8
HTTP 出参 NewHandler(w, r) Success / Error / ErrorData
中间件 MiddlewareChain() Append / ThenFunc
迁移 Migrator(dir) Up / Down / Status
生命周期 Close() / Warmup(...) 收口 / 启动预热

MustXxx 仅用于 main / 启动注入(失败 panic

func NewUserService(app *factory.Factory) *UserService {
    return &UserService{db: app.MustDatabase(), rds: app.MustRedis()}
}

6. HTTP 统一出参

层级 职责
Service 返回数据或 error
Handler 解析、调 Service、h.Success / h.Error
http.Handler 统一 JSON 信封、i18n、timestamp

响应格式HTTP 恒 200

{ "code": 0, "message": "success", "timestamp": 1704067200, "data": {} }

分页 data{ "list", "total", "page", "pageSize" }

h := app.NewHandler(w, r) // 自动注入已配置的 i18n

var req ListUserRequest
if err := h.ParseJSON(&req); err != nil {
    h.Error("common.invalid_request")
    return
}
users, total, err := svc.List(h.Pagination().GetPage(), h.Pagination().GetPageSize())
if err != nil {
    h.Error("user.list_failed")
    return
}
h.SuccessPage(users, total)

请求头:Accept-Language(语种)、X-Timezone(默认 Asia/Shanghai)。


7. 数据库迁移

cp templates/migrate/main.go cmd/migrate/main.go
go build -o bin/migrate cmd/migrate/main.go
./bin/migrate up|status|down

模板默认走 FactoryMustInit + 日志 + Warmup(Database) + Migrator + Close;同样可用 buildOptions() 注入自定义 DB/Logger。

-- migrations/20240101000001_create_users.sql
CREATE TABLE users (id BIGINT PRIMARY KEY AUTO_INCREMENT, username VARCHAR(255) NOT NULL);

-- migrations/20240101000001_create_users.down.sql
DROP TABLE IF EXISTS users;

8. 模块速查

// 日志
app.MustLogger().Info("服务启动", nil)

// 存储
store, _ := app.Storage()
_ = store.Upload(ctx, "images/a.jpg", reader, "image/jpeg")

// 邮件 / 短信HTTP 通知用 Async验证码用同步
app.MustEmail().SendEmailAsync(ctx, []string{"a@b.com"}, "主题", "正文")
app.MustSMS().SendSMSAsync(ctx, []string{"13800138000"}, map[string]string{"code": "123456"})

// Excel
app.Excel().ExportToFile("users.xlsx", "用户列表", columns, users)

// i18nlocales 目录;出参经 NewHandler 自动用)
app.MustI18n().GetMessage("zh-CN", "user.not_found")

// tools不经 Factory
tools.Now()
tools.MD5("text")

MCP 工具Model Context ProtocolClient

本库只做 MCP Client:按配置连接外部 MCP server容器/服务),发现工具、调用工具; 不含路由/抽参/编排逻辑——用哪个工具、怎么填参数、怎么组合答复,属于业务侧的 Prompt/Agent 编排,需要业务项目自行实现(可参考已有 RAG 项目里的 ToolOrchestrator 写法)。

m := app.MustMCP() // config.mcp 未配置或 enabled=false 时 m.Enabled() 为 false

tools, _ := m.ListTools(ctx) // 聚合全部已启用 server 的工具FQName = "{toolNamePrefix}__{原始工具名}"
res, _ := m.CallTool(ctx, "word__create_document", map[string]any{"title": "周报"})

// 可选:把 HTTP 层的 request id 传入,调用日志会附带该字段(不传不影响功能)
ctx = mcp.WithRequestID(ctx, requestID)

config.jsonmcp.servers[] 一条 = 一个独立 MCP server自带多个工具新增能力 = 加一条配置,不改代码;allowedTools 留空表示开放该 server 全部工具。完整字段见 config/example.jsonmcp 段。


9. 最小 config.json

{
  "database": {
    "type": "mysql",
    "host": "localhost",
    "port": 3306,
    "user": "root",
    "password": "password",
    "database": "mydb"
  },
  "logger": {
    "level": "info",
    "output": "both",
    "filePath": "./logs/app.log",
    "async": true
  },
  "i18n": {
    "defaultLang": "zh-CN",
    "localesDir": "locales"
  }
}

完整字段见 config/example.json


10. 反模式

  • Handler 内重复 Init
  • Service 拼 HTTP JSON / 自定义 Response
  • 自行 gorm.Open / redis.NewClient
  • Factory 透传(LogInfoSuccessNow 等)
  • 请求路径滥用 MustXxx
  • 把 MCP 工具路由/抽参/Prompt 编排逻辑塞进本库(应在业务侧基于 mcp.Manager 自行实现)

11. 故障排除

问题 处理
无法下载模块 检查 GOPRIVATE 与 SSH insteadOf
依赖异常 go clean -modcache && go mod tidy
getter 报 config is nil 补配置段,或不调用该模块
迁移找不到文件 检查 -dir 与 SQL 命名

版本发布见 VERSION.md