morning-coffee/app.go

67 lines
1.4 KiB
Go

package main
import (
"fmt"
"log/slog"
"net/http"
"time"
)
type Route struct {
Path string
Handler http.HandlerFunc
}
type BackgroundTask struct {
Handler func()
Interval time.Duration
}
type App struct {
Routes []Route
BackgroundTasks []BackgroundTask
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 App) 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))))
}
for _, task := range a.BackgroundTasks {
go func() {
for {
task.Handler()
time.Sleep(task.Interval)
}
}()
}
http.ListenAndServe(addr, nil)
}
func (a *App) AddRoute(path string, handler http.HandlerFunc) {
a.Routes = append(a.Routes, Route{Path: path, Handler: handler})
}
func NewApp(routes map[string]http.HandlerFunc, backgroundTasks []BackgroundTask, staticRoot string) *App {
app := App{StaticRoot: staticRoot, BackgroundTasks: backgroundTasks}
for route, handler := range routes {
app.AddRoute(route, handler)
}
return &app
}