package main import ( "flag" "net/http" "os" "git.toowon.com/jimmy/go-common/factory" "git.toowon.com/jimmy/go-common/middleware" ) // 业务 HTTP 服务脚手架。 // // mkdir -p cmd/server // cp templates/server/main.go cmd/server/main.go // // 默认已接好:Factory 初始化、日志、默认中间件链、NewHandler 出参、Close 收口。 // 按需改:buildOptions / setupMiddleware / registerRoutes / Warmup 模块列表。 func main() { configPath := flag.String("config", envOr("CONFIG_FILE", "config.json"), "配置文件路径") addr := flag.String("addr", envOr("HTTP_ADDR", ":8080"), "监听地址") flag.Parse() app := factory.MustInit(*configPath, buildOptions()...) defer app.Close() log := app.MustLogger() // 启动期预热:按业务实际使用的模块增删(未配置的模块 Warmup 会失败) if err := app.Warmup( factory.ModuleLogger, // factory.ModuleI18n, // factory.ModuleDatabase, // factory.ModuleRedis, ); err != nil { log.Error("warmup failed", map[string]any{"error": err.Error()}) os.Exit(1) } chain := setupMiddleware(app) mux := http.NewServeMux() registerRoutes(mux, chain, app) log.Info("server starting", map[string]any{"addr": *addr, "config": *configPath}) if err := http.ListenAndServe(*addr, mux); err != nil { log.Error("server stopped", map[string]any{"error": err.Error()}) os.Exit(1) } } // buildOptions 组装 Factory Option(自定义实现 / 测试替身在此注入) func buildOptions() []factory.Option { // 默认不注入,全部走 config.json lazy 初始化。 // 需要替换实现时取消注释,例如: // // return []factory.Option{ // factory.WithLogger(customLogger), // factory.WithStorage(customStorage), // factory.WithDatabase(db), // factory.WithRedis(rds), // factory.WithI18n(i18nInst), // factory.WithMiddlewareChain(customChain), // } return nil } // setupMiddleware 基于 Factory 默认链追加业务中间件 // 默认链:Recovery → RequestID → Logging → RateLimit? → CORS? → Language → Timezone func setupMiddleware(app *factory.Factory) *middleware.Chain { chain := app.MiddlewareChain() // 业务鉴权等自行挂载(本库不提供登录体系) // chain.Append(authMiddleware) // chain.Append(permissionMiddleware) return chain } // registerRoutes 注册路由;出参统一用 app.NewHandler func registerRoutes(mux *http.ServeMux, chain *middleware.Chain, app *factory.Factory) { mux.Handle("/api/ping", chain.ThenFunc(func(w http.ResponseWriter, r *http.Request) { h := app.NewHandler(w, r) h.Success(map[string]string{"status": "ok"}) })) // 示例:业务路由 // mux.Handle("/api/users", chain.ThenFunc(func(w http.ResponseWriter, r *http.Request) { // h := app.NewHandler(w, r) // // ... // h.Success(nil) // })) } func envOr(key, fallback string) string { if v := os.Getenv(key); v != "" { return v } return fallback }