Files
comicverse/router/router.go
Gustavo "Guz" L de Mello eb53285f03 feat(service): new service abstraction to directly interact with DBs and operations
This should make the router be just about HTML rendering, paramaters
validation and routing.
2025-03-11 09:40:48 -03:00

124 lines
2.7 KiB
Go

package router
import (
"errors"
"html/template"
"io/fs"
"log/slog"
"net/http"
"forge.capytal.company/capytalcode/project-comicverse/service"
"forge.capytal.company/loreddev/x/smalltrip"
"forge.capytal.company/loreddev/x/smalltrip/exception"
"forge.capytal.company/loreddev/x/smalltrip/middleware"
"forge.capytal.company/loreddev/x/tinyssert"
)
type router struct {
service service.Service
templates *template.Template
staticFiles fs.FS
cache bool
assert tinyssert.Assertions
log *slog.Logger
}
func New(cfg Config) (http.Handler, error) {
if cfg.Service == nil {
return nil, errors.New("service is nil")
}
if cfg.Templates == nil {
return nil, errors.New("templates is nil")
}
if cfg.StaticFiles == nil {
return nil, errors.New("static files is nil")
}
if cfg.Assertions == nil {
return nil, errors.New("assertions is nil")
}
if cfg.Logger == nil {
return nil, errors.New("logger is nil")
}
r := &router{
templates: cfg.Templates,
staticFiles: cfg.StaticFiles,
cache: !cfg.DisableCache,
assert: cfg.Assertions,
log: cfg.Logger,
}
return r.setup(), nil
}
type Config struct {
Service service.Service
Templates *template.Template
StaticFiles fs.FS
DisableCache bool
Assertions tinyssert.Assertions
Logger *slog.Logger
}
func (router *router) setup() http.Handler {
router.assert.NotNil(router.log)
router.assert.NotNil(router.staticFiles)
log := router.log
log.Debug("Initializing router")
r := smalltrip.NewRouter(
smalltrip.WithAssertions(router.assert),
smalltrip.WithLogger(log.WithGroup("smalltrip")),
)
r.Use(middleware.Logger(log.WithGroup("requests")))
if router.cache {
r.Use(middleware.Cache())
} else {
r.Use(middleware.DisableCache())
}
r.Use(exception.PanicMiddleware())
r.Use(exception.Middleware())
r.Handle("/static", http.StripPrefix("/static/", http.FileServerFS(router.staticFiles)))
r.HandleFunc("/dashboard", router.dashboard)
r.HandleFunc("GET /projects", router.listProjects)
r.HandleFunc("POST /projects", router.newProject)
return r
}
func (router *router) dashboard(w http.ResponseWriter, r *http.Request) {
router.assert.NotNil(router.templates)
router.assert.NotNil(w)
router.assert.NotNil(r)
w.WriteHeader(http.StatusOK)
err := router.templates.ExecuteTemplate(w, "dashboard", nil)
if err != nil {
exception.InternalServerError(err).ServeHTTP(w, r)
}
}
func (router *router) listProjects(w http.ResponseWriter, r *http.Request) {
router.assert.NotNil(router.templates)
router.assert.NotNil(w)
router.assert.NotNil(r)
}
func (router *router) newProject(w http.ResponseWriter, r *http.Request) {
router.assert.NotNil(router.templates)
router.assert.NotNil(w)
router.assert.NotNil(r)
}