You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
117 lines
2.8 KiB
117 lines
2.8 KiB
package server |
|
|
|
import ( |
|
"context" |
|
"net/http" |
|
"strconv" |
|
"time" |
|
|
|
"github.com/gin-gonic/gin" |
|
|
|
"autostore/internal/application/interfaces" |
|
"autostore/internal/presentation/controllers" |
|
"autostore/internal/presentation/middleware" |
|
) |
|
|
|
type Server struct { |
|
config *Config |
|
logger interfaces.ILogger |
|
itemsCtrl *controllers.ItemsController |
|
authCtrl *controllers.AuthController |
|
jwtMiddleware *middleware.JWTMiddleware |
|
httpServer *http.Server |
|
} |
|
|
|
type Config struct { |
|
Port int |
|
ReadTimeout time.Duration |
|
WriteTimeout time.Duration |
|
ShutdownTimeout time.Duration |
|
} |
|
|
|
func NewServer( |
|
config *Config, |
|
logger interfaces.ILogger, |
|
itemsCtrl *controllers.ItemsController, |
|
authCtrl *controllers.AuthController, |
|
jwtMiddleware *middleware.JWTMiddleware, |
|
) *Server { |
|
return &Server{ |
|
config: config, |
|
logger: logger, |
|
itemsCtrl: itemsCtrl, |
|
authCtrl: authCtrl, |
|
jwtMiddleware: jwtMiddleware, |
|
} |
|
} |
|
|
|
func (s *Server) Start() error { |
|
gin.SetMode(gin.ReleaseMode) |
|
router := s.SetupRoutes() |
|
|
|
s.httpServer = &http.Server{ |
|
Addr: ":" + strconv.Itoa(s.config.Port), |
|
Handler: router, |
|
ReadTimeout: s.config.ReadTimeout, |
|
WriteTimeout: s.config.WriteTimeout, |
|
} |
|
|
|
s.logger.Info(context.Background(), "Server starting on port %d", s.config.Port) |
|
return s.httpServer.ListenAndServe() |
|
} |
|
|
|
func (s *Server) Shutdown(ctx context.Context) error { |
|
s.logger.Info(ctx, "Server shutting down") |
|
|
|
shutdownCtx, cancel := context.WithTimeout(ctx, s.config.ShutdownTimeout) |
|
defer cancel() |
|
|
|
return s.httpServer.Shutdown(shutdownCtx) |
|
} |
|
|
|
func (s *Server) SetupRoutes() *gin.Engine { |
|
router := gin.New() |
|
|
|
// Middleware |
|
router.Use(gin.Recovery()) |
|
router.Use(s.corsMiddleware()) |
|
|
|
// Health check |
|
router.GET("/health", func(c *gin.Context) { |
|
c.JSON(http.StatusOK, gin.H{"status": "ok"}) |
|
}) |
|
|
|
// API v1 group |
|
v1 := router.Group("/api/v1") |
|
|
|
// Auth routes (no JWT middleware) |
|
v1.POST("/login", s.authCtrl.Login) |
|
|
|
// Items routes (with JWT middleware) |
|
items := v1.Group("/items") |
|
items.Use(s.jwtMiddleware.Middleware()) |
|
{ |
|
items.POST("", s.itemsCtrl.CreateItem) |
|
items.GET("", s.itemsCtrl.ListItems) |
|
items.GET("/:id", s.itemsCtrl.GetItem) |
|
items.DELETE("/:id", s.itemsCtrl.DeleteItem) |
|
} |
|
|
|
return router |
|
} |
|
|
|
func (s *Server) corsMiddleware() gin.HandlerFunc { |
|
return func(c *gin.Context) { |
|
c.Header("Access-Control-Allow-Origin", "*") |
|
c.Header("Access-Control-Allow-Credentials", "true") |
|
c.Header("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, origin, Cache-Control, X-Requested-With") |
|
c.Header("Access-Control-Allow-Methods", "POST, OPTIONS, GET, PUT, DELETE") |
|
|
|
if c.Request.Method == "OPTIONS" { |
|
c.AbortWithStatus(204) |
|
return |
|
} |
|
|
|
c.Next() |
|
} |
|
}
|
|
|