本文將示範如何在 Clean Architecture 架構下,設計清晰且易於維護的路由層。
internal/http/server.go
: 負責 http.Server
的生命週期管理,包括 graceful shutdown。internal/http/middleware/*.go
: 定義全域中介軟體,如日誌、CORS、錯誤處理等。internal/http/route.go
: 路由的總入口,負責註冊全域中介軟體和呼叫特定路由的設定函式。internal/http/route_api.go
: 負責註冊所有 /api
API 相關的路由。internal/http/route_root.go
: 負責註冊根路由,如健康檢查、靜態資源等。接下來,我們將深入探討每個檔案的具體實作。
server.go
:HTTP 伺服器的啟動 與 Graceful Shutdownserver.go
的核心職責是管理 http.Server
的完整生命週期。
一個良好的伺服器不僅要能正確啟動,更重要的是能在接收到關閉信號時(例如 Ctrl+C
或 kill
命令),實現 Graceful Shutdown。
我們使用 http.Server
來設定伺服器的基本參數,如地址、處理器(Handler)、讀寫逾時等。
internal/http/server.go
func NewServer(app *application.Application) (*Server, error) {
engine := gin.New()
engine.Use(gin.Recovery())
engine.Use(middleware.NewRequestLogger(app.Logger).Execute())
engine.Use(middleware.NewInjectLogger(app.Logger).Execute())
registerRoutes(engine, app)
server := &http.Server{
Addr: ":" + app.Config.Server.Port,
Handler: engine,
ReadTimeout: defaultHTTPServerReadHeaderTimeout,
}
return &Server{
server: server,
engine: engine,
}, nil
}
我們使用的 gin.New()
來建立一個新的 Gin 引擎,
註冊了一個 gin 內建的 Recovery Middleware,
以及兩個自訂的 Middleware:RequestLogger
和 InjectLogger
。
為什麼會需要 Recovery Middleware 呢?因為它能捕捉任何未處理的 panic,
防止伺服器直接被關閉,並回應 500 錯誤給客戶端。
但是如果你的服務器架構有監控系統(如 Kubernetes),你也可以選擇不使用 Recovery Middleware,
讓服務器在發生 panic 時直接崩潰,然後由監控系統自動開啟新的 Server Instance 來處理請求。
Graceful Shutdown 意味著:
這樣可以避免中斷正在執行的操作,確保資料一致性,並提升系統的可靠性。
route.go
:路由的總指揮route.go
是路由設定的總入口。它的職責很單純:
gin.Engine
實例。route_*.go
檔案。application.Application
物件,讓各個路由設定函式能夠存取應用程式的服務。application.Application
物件呢?這是要完成 Deep Dependency Injection 的目的。這種做法讓路由管理更有條理。當專案規模擴大時,
我們可以輕易地新增 route_admin.go
或 route_v2.go
等檔案,
而不需要修改 route.go
的核心邏輯。
route_root.go
& route_api.go
:模組化的路由註冊這兩個檔案分別定義了不同路徑前綴的路由。
route_root.go
:通常用於註冊服務狀態相關的端點,例如健康檢查 (/healthz
) 或指標 (/metrics
)。route_api.go
:是 API 的主要入口,所有業務邏輯相關的 API 都會在這裡註冊,並以 /api
作為前綴。我們會在之後的篇章中,詳細介紹如何在 route_api.go
中註冊具體的 API 路由。
middleware
:中介層Middleware 是 Gin 框架的核心優勢之一。
它允許我們在請求處理流程中插入自訂邏輯,
非常適合處理日誌、認證、CORS、錯誤恢復等。
在我們的架構中,internal/http/middleware
目錄存放了所有自訂的中介軟體。
目前我們實作了兩個 Middleware:
RequestLogger
:負責記錄每個請求的詳細資訊,如方法、路徑、狀態碼、處理時間等。InjectLogger
:將 Logger 注入到 Gin 的 Context 中,讓後續的處理程式碼可以方便地使用 logger。本文介紹了如何在 Clean Architecture 架構下,使用 Gin 框架設計清晰且易於維護的路由層。
我們探討了伺服器的生命週期管理、路由的模組化,以及 Middleware 的應用。
這種結構不僅提升了程式碼的可讀性和可維護性,也為未來的擴展和修改奠定了基礎。
以上程式碼的完整內容可以到 Github 觀看