package main import ( "fmt" "log/slog" "net/http" "time" ) type Route struct { Path string Handler http.HandlerFunc } type API struct { Routes []Route StaticRoot string } func LoggingMiddleware(f http.HandlerFunc) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { start := time.Now() f(w, r) slog.Info(fmt.Sprintf("%s - %s (%dms)", r.Method, r.URL, time.Now().Sub(start).Milliseconds())) } } func (a API) Start(addr string) { for _, route := range a.Routes { http.HandleFunc(route.Path, LoggingMiddleware(route.Handler)) } if a.StaticRoot != "" { http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir(a.StaticRoot)))) } http.ListenAndServe(addr, nil) } func (a *API) AddRoute(path string, handler http.HandlerFunc) { a.Routes = append(a.Routes, Route{Path: path, Handler: handler}) }