80 lines
1.9 KiB
Go
80 lines
1.9 KiB
Go
|
package handlers
|
||
|
|
||
|
import (
|
||
|
"io/fs"
|
||
|
"net/http"
|
||
|
"time"
|
||
|
|
||
|
"git.vbrandl.net/vbrandl/go-web-template/service"
|
||
|
"github.com/gorilla/mux"
|
||
|
"github.com/justinas/alice"
|
||
|
"github.com/rs/zerolog/hlog"
|
||
|
"github.com/rs/zerolog/log"
|
||
|
)
|
||
|
|
||
|
type Application struct {
|
||
|
Service *service.Service
|
||
|
StaticFiles fs.FS
|
||
|
}
|
||
|
|
||
|
func NewApplication(service *service.Service, staticFiles fs.FS) (Application, error) {
|
||
|
application := Application{
|
||
|
Service: service,
|
||
|
StaticFiles: staticFiles,
|
||
|
}
|
||
|
|
||
|
err := application.ParseTemplates()
|
||
|
|
||
|
return application, err
|
||
|
}
|
||
|
|
||
|
func (app *Application) Routes() *mux.Router {
|
||
|
router := mux.NewRouter().StrictSlash(true)
|
||
|
|
||
|
router.HandleFunc("/", app.Index).Methods("GET")
|
||
|
router.HandleFunc("/health", app.HealthCheck).Methods("GET")
|
||
|
|
||
|
// strip off the location such that we route correctly
|
||
|
staticContent, err := fs.Sub(app.StaticFiles, "static")
|
||
|
if err != nil {
|
||
|
log.Fatal().Err(err).Msg("error with static content")
|
||
|
}
|
||
|
f := http.FileServerFS(staticContent)
|
||
|
router.PathPrefix("/static/").Handler(http.StripPrefix("/static", f))
|
||
|
|
||
|
router.NotFoundHandler = http.HandlerFunc(app.NotFound)
|
||
|
|
||
|
return router
|
||
|
}
|
||
|
|
||
|
func (app *Application) Handler() http.Handler {
|
||
|
logger := log.Logger
|
||
|
middlewares := alice.New().
|
||
|
Append(hlog.NewHandler(logger)).
|
||
|
Append(hlog.AccessHandler(func(r *http.Request, status int, size int, duration time.Duration) {
|
||
|
hlog.FromRequest(r).Info().
|
||
|
Str("method", r.Method).
|
||
|
Stringer("url", r.URL).
|
||
|
Int("status", status).
|
||
|
Int("size", size).
|
||
|
Str("remote-addr", r.RemoteAddr).
|
||
|
Dur("duration", duration).
|
||
|
Str("user-agent", r.UserAgent()).
|
||
|
Msg("")
|
||
|
})).
|
||
|
Append(hlog.RequestIDHandler("request-id", "x-request-id"))
|
||
|
|
||
|
routes := app.Routes()
|
||
|
return middlewares.Then(routes)
|
||
|
}
|
||
|
|
||
|
func RequestID(r *http.Request) string {
|
||
|
if id, ok := hlog.IDFromRequest(r); ok {
|
||
|
return id.String()
|
||
|
} else {
|
||
|
l := hlog.FromRequest(r)
|
||
|
l.Warn().Msg("No associated request ID")
|
||
|
return "unknown"
|
||
|
}
|
||
|
}
|