调整项目架构,让框架更优化
This commit is contained in:
100
templates/server/main.go
Normal file
100
templates/server/main.go
Normal file
@@ -0,0 +1,100 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user