Refactor router setup to split routes by auth/protected boundary

This commit is contained in:
2026-04-27 23:30:17 +08:00
parent 7fb125ea87
commit d4d7495ffb
5 changed files with 31 additions and 19 deletions

View File

@@ -75,5 +75,5 @@ Applied to protected groups: auth (JWT validation, inject user into gin.Context)
- `cmd/serve.go` loads config, creates `app.WebApp`, builds the router, and starts the HTTP server.
- `app.WebApp` carries runtime dependencies and build metadata needed to assemble handlers.
- `internal/server` owns Gin router setup, `/api/v1` route groups, and HTTP server lifecycle.
- `internal/server` owns Gin router setup (`router.go`), route registration split into `routes_public.go` and `routes_protected.go`, and HTTP server lifecycle.
- `RunWithGracefulShutdown` stops accepting new requests on termination and gives in-flight requests time to finish.

View File

@@ -40,11 +40,11 @@
| Success responses | Direct JSON resource bodies | Use HTTP status codes as the request outcome signal. |
| Error responses | `{"error":{"message":"..."}}` | Add machine-readable error codes only when clients need stable branching behavior. |
| App composition | `internal/app.WebApp` | `cmd/serve.go` creates the app from config and build metadata, then passes it to router setup. |
| Router setup | `internal/server.NewRouter(*app.WebApp)` | Register public and protected route groups in one readable router file. |
| Router setup | `internal/server.NewRouter(*app.WebApp)` | Public routes (`routes_public.go`) and protected routes (`routes_protected.go`) split by auth boundary; `WebApp` serves as the unified dependency container. |
| Server lifecycle | `RunWithGracefulShutdown` | Preserve graceful shutdown while keeping command startup linear. |
| Default middleware | `gin.Default()` | Use default logger/recovery for the skeleton; add CORS/auth explicitly when their policies exist. |
**Consequences**:
- Version is build metadata from `internal/version`, not a config-file field.
- Version is build metadata from `internal/app/version.go`, not a config-file field.
- `app.WebApp` is the place to add future services, repositories, storage, and app metadata incrementally.
- Request ID middleware is not part of the current foundation; add it only with a logging/tracing/error-correlation design.

View File

@@ -4,29 +4,16 @@ import (
"github.com/gin-gonic/gin"
"github.com/dhao2001/mygo/internal/app"
"github.com/dhao2001/mygo/internal/handler"
)
// NewRouter builds the Gin router and registers API routes.
func NewRouter(webApp *app.WebApp) *gin.Engine {
router := gin.Default()
rootGroup := router.Group("/api/v1")
v1 := router.Group("/api/v1")
publicGroup := rootGroup.Group("")
setupVersionRoutes(publicGroup, handler.NewVersionHandler(webApp.Version))
authGroup := rootGroup.Group("")
setupProtectedRoutes(authGroup)
setupPublicRoutes(v1, webApp)
setupProtectedRoutes(v1, webApp)
return router
}
func setupVersionRoutes(rg *gin.RouterGroup, h *handler.VersionHandler) {
rg.GET("/version", h.Get)
}
func setupProtectedRoutes(rg *gin.RouterGroup) {
// Protected routes will be registered after auth middleware exists.
_ = rg
}

View File

@@ -0,0 +1,12 @@
package server
import (
"github.com/gin-gonic/gin"
"github.com/dhao2001/mygo/internal/app"
)
func setupProtectedRoutes(rg *gin.RouterGroup, _ *app.WebApp) {
_ = rg
// Protected routes will be registered after auth middleware is implemented.
}

View File

@@ -0,0 +1,13 @@
package server
import (
"github.com/gin-gonic/gin"
"github.com/dhao2001/mygo/internal/app"
"github.com/dhao2001/mygo/internal/handler"
)
func setupPublicRoutes(rg *gin.RouterGroup, webApp *app.WebApp) {
versionHandler := handler.NewVersionHandler(webApp.Version)
rg.GET("/version", versionHandler.Get)
}