package handlers import ( "hamster-tycoon/middlewares" "hamster-tycoon/service" "hamster-tycoon/storage/dao" "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 cageService *service.CageService hamsterService *service.HamsterService } 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{} hc.db = postgresql.NewDatabasePostgreSQL(config.DBConnectionURI) hc.validator = newValidator() hc.userService = service.NewUserService(hc.db) hc.cageService = service.NewCageService(hc.db) hc.hamsterService = service.NewHamsterService(hc.db) public := router.Group("/") public.Handle(http.MethodGet, "/_health", hc.GetHealth) userRoute := public.Group("/users") userRoute.Handle("LOGIN", "", hc.connectUser) userRoute.Handle(http.MethodPost, "", hc.createUser) securedUserRoute := userRoute.Group("") //TODO add secure auth securedUserRoute.Handle(http.MethodGet, "", hc.getAllUsers) securedUserRoute.Handle(http.MethodGet, "/:userID", hc.getUser) securedUserRoute.Handle(http.MethodPut, "/:userID", hc.updateUser) securedUserRoute.Handle(http.MethodDelete, "/:userID", hc.deleteUser) // end: user routes cageRoute := securedUserRoute.Group("/cages") cageRoute.Handle(http.MethodGet, "", hc.getAllCages) cageRoute.Handle(http.MethodGet, "/:cageID", hc.getACage) //cageRoute.Handle(http.MethodPost, "/:cageID", hc.createACage) //cageRoute.Handle(http.MethodPut, "/:cageID", hc.updateACage) //cageRoute.Handle(http.MethodDelete, "/:cageID", hc.deleteACage) hamsterRoute := cageRoute.Group("/:cageID/hamsters") hamsterRoute.Handle(http.MethodGet, "", hc.getAllHamsters) hamsterRoute.Handle(http.MethodGet, "/:hamsterID", hc.getAHamster) hamsterRoute.Handle(http.MethodPost, "/:hamsterID", hc.createAHamster) hamsterRoute.Handle(http.MethodPut, "/:hamsterID", hc.updateAHamster) hamsterRoute.Handle(http.MethodDelete, "/:hamsterID", hc.deleteAHamster) 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 }