package httpserver 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" ) func (s *server) routes() { 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.RequestID) s.router.Use(s.LoggingMiddleware()) s.router.Use(s.MetricsMiddleware()) // 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. this was at the // bottom, but chi requires *all* middlewares applied before any // routes are, so now it's up here. unfortunately this cannot // coexist with the normal chi Recoverer handler which prints a nice // colorful stack trace to the console if s.sentryEnabled { // Options docs at // https://docs.sentry.io/platforms/go/guides/http/ sentryHandler := sentryhttp.New(sentryhttp.Options{}) s.router.Use(sentryHandler.Handle) // FYI: the sentry panic-catcher seems to set the response // code to 200. } else { // FYI: the chi Recoverer middleware sets the response code // on panics to 500. s.router.Use(middleware.Recoverer) } //////////////////////////////////////////////////////////////////////// // ROUTES // complete docs: https://github.com/go-chi/chi //////////////////////////////////////////////////////////////////////// s.router.Get("/", s.handleIndex()) // 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: authMiddleware := s.AuthMiddleware() s.router.Get( "/login", authMiddleware(s.handleLogin()).ServeHTTP, ) s.router.Get( "/.well-known/healthcheck.json", s.handleHealthCheck(), ) // route that panics for testing // CHANGEME remove this s.router.Get( "/panic", s.handlePanic(), ) // CHANGEME you probably want to wrap the following in some kind of // auth like http basic auth which is easy to set up on your // rometheus collector // TODO(sneak): read http basic auth user/pass for /metrics // out of environment vars s.router.Get( "/metrics", http.HandlerFunc(promhttp.Handler().ServeHTTP), ) }