package server import ( "net/http" "time" sentryhttp "github.com/getsentry/sentry-go/http" "github.com/go-chi/chi" "github.com/go-chi/chi/middleware" "github.com/prometheus/client_golang/prometheus/promhttp" "github.com/spf13/viper" ) func (s *Server) SetupRoutes() { s.router = chi.NewRouter() // the mux .Use() takes a http.Handler wrapper func, like most // things that deal with "middlewares" like alice et c, and will // call ServeHTTP on it. These middlewares applied by the mux (you // can .Use() more than one) will be applied to every request into // the service. s.router.Use(middleware.Recoverer) s.router.Use(middleware.RequestID) s.router.Use(s.mw.Logging()) // add metrics middleware only if we can serve them behind auth if viper.GetString("METRICS_USERNAME") != "" { s.router.Use(s.mw.Metrics()) } // set up CORS headers. you'll probably want to configure that // in middlewares.go. s.router.Use(s.mw.CORS()) // CHANGEME to suit your needs, or pull from config. // timeout for request context; your handlers must finish within // this window: s.router.Use(middleware.Timeout(60 * time.Second)) // this adds a sentry reporting middleware if and only if sentry is // enabled via setting of SENTRY_DSN in env. if s.sentryEnabled { // Options docs at // https://docs.sentry.io/platforms/go/guides/http/ // we set sentry to repanic so that all panics bubble up to the // Recoverer chi middleware above. sentryHandler := sentryhttp.New(sentryhttp.Options{ Repanic: true, }) s.router.Use(sentryHandler.Handle) } //////////////////////////////////////////////////////////////////////// // ROUTES // complete docs: https://github.com/go-chi/chi //////////////////////////////////////////////////////////////////////// s.router.Get("/", s.h.HandleIndex()) s.router.Mount("/s", http.StripPrefix("/s", http.FileServer(http.FS(static.Static)))) s.router.Route("/api/v1", func(r chi.Router) { r.Get("/now", s.h.HandleNow()) }) // if you want to use a general purpose middleware (http.Handler // wrapper) on a specific HandleFunc route, you need to take the // .ServeHTTP of the http.Handler to get its HandleFunc, viz: auth := s.mw.Auth() s.router.Get( "/login", auth(s.h.HandleLoginGET()).ServeHTTP, ) s.router.Get( "/signup", auth(s.h.HandleSignupGET()).ServeHTTP, ) s.router.Post( "/signup", auth(s.h.HandleSignupPOST()).ServeHTTP, ) // route that panics for testing // CHANGEME remove this s.router.Get( "/panic", s.h.HandlePanic(), ) s.router.Get( "/.well-known/healthcheck.json", s.h.HandleHealthCheck(), ) // set up authenticated /metrics route: if viper.GetString("METRICS_USERNAME") != "" { s.router.Group(func(r chi.Router) { r.Use(s.mw.MetricsAuth()) r.Get("/metrics", http.HandlerFunc(promhttp.Handler().ServeHTTP)) }) } }