package handlers import ( "hamster-tycoon/middlewares" "hamster-tycoon/service" "hamster-tycoon/storage/dao" "hamster-tycoon/storage/dao/fake" "hamster-tycoon/storage/dao/postgresql" "hamster-tycoon/storage/validators" "net/http" "time" "reflect" "strings" "github.com/gin-contrib/cors" "github.com/gin-gonic/gin" "gopkg.in/go-playground/validator.v9" ) type Config struct { Mock bool DBConnectionURI string Port int LogLevel string LogFormat string } type handlersContext struct { db dao.Database validator *validator.Validate userService *service.UserService } func NewRouter(config *Config) *gin.Engine { gin.SetMode(gin.ReleaseMode) router := gin.New() router.HandleMethodNotAllowed = true router.Use(cors.New(cors.Config{ AllowOrigins: []string{"*"}, AllowMethods: []string{"*"}, AllowHeaders: []string{"*"}, ExposeHeaders: []string{"*"}, AllowCredentials: true, MaxAge: 12 * time.Hour, })) router.Use(gin.Recovery()) router.Use(middlewares.GetLoggerMiddleware()) router.Use(middlewares.GetHTTPLoggerMiddleware()) hc := &handlersContext{} if config.Mock { hc.db = fake.NewDatabaseFake() } else { hc.db = postgresql.NewDatabasePostgreSQL(config.DBConnectionURI) } hc.validator = newValidator() hc.userService = service.NewUserService(hc.db) public := router.Group("/") public.Handle(http.MethodGet, "/_health", hc.GetHealth) public.Handle("LOGIN", "/users", hc.ConnectUser) // start: user routes public.Handle(http.MethodGet, "/users", hc.GetAllUsers) public.Handle(http.MethodPost, "/users", hc.CreateUser) public.Handle(http.MethodGet, "/users/:id", hc.GetUser) public.Handle(http.MethodPut, "/users/:id", hc.UpdateUser) public.Handle(http.MethodDelete, "/users/:id", hc.DeleteUser) // end: user routes return router } func newValidator() *validator.Validate { va := validator.New() va.RegisterTagNameFunc(func(fld reflect.StructField) string { name := strings.SplitN(fld.Tag.Get("json"), ",", 2) if len(name) < 1 { return "" } return name[0] }) for k, v := range validators.CustomValidators { if v.Validator != nil { va.RegisterValidationCtx(k, v.Validator) } } return va }