chore: refactored sl and added an hooks system

modified: cmd/dev-server/main.go, cmd/server/main.go

    Aggiornati per utilizzare il nuovo sistema degli hooks, ora nei "main" vanno
    solo chiamate "ProvideValue", "Provide" e "ProvideHook" ed una finale
    di "Invoke" o "Use". Mentre nei vari servizi vanno solo chiamate "Use"
    o "UseHook"

modified: libs/sl/sl.go

    Rinominati "InjectValue" e "InjectLazy" a "Provide" e "ProvideFunc", altro
    refactor di varie cose ed aggiunto il concetto degli hook per poter
    iniettare anche più di un servizio dentro un altro in un preciso ordine.

modified: server/config/config.go

    Lieve refactor ed aggiunta la variabile "NPM_COMMAND" configurabile per la
    fase di development.

modified: server/listautenti/listautenti.go

    Ora questo è un vero e proprio servizio "state-less", fornisce solo una
    funzione che monta tutte le route necessarie a questo servizio. Più avanti
    dipenderà da LDAP quindi forse sarà leggermente più complicato.

modified: server/listautenti/listautenti_test.go

    Aggiornato questo test, ora usa il nuovo sistema e funge di nuovo.

deleted: server/routes/routes.go

    Il sistema degli hook è stato introdotto anche per semplificare questa cosa
    che ora infatti non serve più.

modified: server/server.go

    Ora il server non chiama più "InjectValue" con i sotto-router ma espone solo
    un hook che passa i sotto router come parametri, in questo modo è più
    facile aggiungere e togliere servizi direttamente alla radice quando viene
    configurata tutta l'applicazione.
This commit is contained in:
2023-06-14 12:41:34 +02:00
parent be8c35229b
commit 01982942a8
8 changed files with 246 additions and 124 deletions
+21 -12
View File
@@ -9,37 +9,46 @@ import (
type Config struct {
Mode string
Host string
NpmCommand string
}
var Slot = sl.NewSlot[Config]()
func setFromEnvOrDefault(target *string, m map[string]string, key string, defaultValue string) {
v, ok := m[key]
if ok {
*target = v
} else {
*target = defaultValue
}
}
func Configure(l *sl.ServiceLocator) (Config, error) {
m, err := godotenv.Read(".env")
env, err := godotenv.Read(".env")
if err != nil {
return Config{}, err
}
var cfg Config
cfg.Mode = "production"
if v, ok := m["MODE"]; ok {
cfg.Mode = v
}
cfg.Host = ":4000"
if v, ok := m["HOST"]; ok {
cfg.Host = v
}
setFromEnvOrDefault(&cfg.Mode, env, "MODE", "production")
setFromEnvOrDefault(&cfg.Host, env, "HOST", ":4000")
setFromEnvOrDefault(&cfg.NpmCommand, env, "NPM_COMMAND", "npm")
return cfg, nil
}
var TestingProductionConfig = Config{
var ExampleProductionConfig = Config{
Mode: "production",
Host: ":4000",
NpmCommand: "npm",
}
var TestingDevelopmentConfig = Config{
var ExampleDevelopmentConfig = Config{
Mode: "development",
Host: ":4000",
NpmCommand: "npm",
}
+4 -14
View File
@@ -6,25 +6,15 @@ import (
"git.phc.dm.unipi.it/phc/website/libs/sl"
"git.phc.dm.unipi.it/phc/website/server/database"
"git.phc.dm.unipi.it/phc/website/server/routes"
)
type ListaUtenti struct{}
var Slot = sl.NewSlot[*ListaUtenti]()
func Configure(l *sl.ServiceLocator) (*ListaUtenti, error) {
func MountApiRoutesHook(l *sl.ServiceLocator, api fiber.Router) error {
db, err := sl.Use(l, database.Slot)
if err != nil {
return nil, err
return err
}
r, err := sl.Use(l, routes.Root)
if err != nil {
return nil, err
}
r.Get("/api/lista-utenti", func(c *fiber.Ctx) error {
api.Get("/lista-utenti", func(c *fiber.Ctx) error {
users, err := db.ReadUsers()
if err != nil {
return err
@@ -34,5 +24,5 @@ func Configure(l *sl.ServiceLocator) (*ListaUtenti, error) {
return c.JSON(users)
})
return &ListaUtenti{}, nil
return nil
}
+28 -21
View File
@@ -10,23 +10,22 @@ import (
"gotest.tools/assert"
"github.com/gofiber/fiber/v2"
"github.com/valyala/fasthttp"
"github.com/valyala/fasthttp/fasthttputil"
"git.phc.dm.unipi.it/phc/website/libs/db"
"git.phc.dm.unipi.it/phc/website/libs/sl"
"git.phc.dm.unipi.it/phc/website/libs/util"
"git.phc.dm.unipi.it/phc/website/server"
"git.phc.dm.unipi.it/phc/website/server/config"
"git.phc.dm.unipi.it/phc/website/server/database"
"git.phc.dm.unipi.it/phc/website/server/listautenti"
"git.phc.dm.unipi.it/phc/website/server/model"
"git.phc.dm.unipi.it/phc/website/server/routes"
)
func TestApiListaUtenti(t *testing.T) {
r := fiber.New()
memDB := &database.Memory{
Users: []model.User{
{
@@ -45,23 +44,35 @@ func TestApiListaUtenti(t *testing.T) {
}
l := sl.New()
sl.InjectValue(l, config.Slot, config.TestingProductionConfig)
sl.InjectValue[database.Database](l, database.Slot, memDB)
sl.InjectValue(l, routes.Root, fiber.Router(r))
listautenti.Configure(l)
// Config
sl.Provide(l, config.Slot, config.ExampleProductionConfig)
// Database
sl.Provide[database.Database](l, database.Slot, memDB)
// Server
sl.ProvideFunc(l, server.Slot, server.Configure)
sl.ProvideHook(l, server.ApiRoutesHook,
listautenti.MountApiRoutesHook,
)
// Initialize server instance
srv, err := sl.Use(l, server.Slot)
assert.NilError(t, err)
//
// Try doing the request
//
req, err := http.NewRequest("GET", "http://localhost:4000/api/lista-utenti", nil)
if err != nil {
t.Error(err)
}
assert.NilError(t, err)
ln := fasthttputil.NewInmemoryListener()
defer ln.Close()
go func() {
err := fasthttp.Serve(ln, r.Handler())
err := fasthttp.Serve(ln, srv.Router.Handler())
if err != nil {
panic(fmt.Errorf("failed to serve: %v", err))
}
@@ -76,27 +87,23 @@ func TestApiListaUtenti(t *testing.T) {
}
res, err := client.Do(req)
if err != nil {
t.Error(err)
}
assert.NilError(t, err)
body, err := io.ReadAll(res.Body)
if err != nil {
t.Error(err)
}
assert.NilError(t, err)
assert.Equal(t, string(body), util.CompactIndentedLines(`
[
{
"Id":"claire",
"Id":"e39ad8d5-a087-4cb2-8fd7-5a6ca3f6a534",
"Username":"claire-doe",
"FullName":"Claire Doe",
"Nickname":"claire-doe",
"Email":"claire.doe@example.org"
},
{
"Id":"john",
"Id":"9b7109cd-95a1-41e9-a9f6-001a32c20ca1",
"Username":"john-smith",
"FullName":"John Smith",
"Nickname":"john-smith",
"Email":"john.smith@example.org"
}
]
-9
View File
@@ -1,9 +0,0 @@
package routes
import (
"git.phc.dm.unipi.it/phc/website/libs/sl"
"github.com/gofiber/fiber/v2"
)
var Root = sl.NewSlot[fiber.Router]()
+19 -7
View File
@@ -1,9 +1,10 @@
package server
import (
"log"
"git.phc.dm.unipi.it/phc/website/libs/sl"
"git.phc.dm.unipi.it/phc/website/server/listautenti"
"git.phc.dm.unipi.it/phc/website/server/routes"
"git.phc.dm.unipi.it/phc/website/server/config"
"github.com/gofiber/fiber/v2"
)
@@ -12,15 +13,26 @@ type Server struct{ Router *fiber.App }
var Slot = sl.NewSlot[*Server]()
var ApiRoutesHook = sl.NewHook[fiber.Router]()
func Configure(l *sl.ServiceLocator) (*Server, error) {
r := fiber.New(fiber.Config{})
r.Static("/assets", "./out/frontend/assets")
sl.InjectValue(l, routes.Root, fiber.Router(r))
if err := sl.Invoke(l, listautenti.Slot); err != nil {
cfg, err := sl.Use(l, config.Slot)
if err != nil {
return nil, err
}
r := fiber.New(fiber.Config{})
r.Static("/assets", "./out/frontend/assets")
api := r.Group("/api")
if err := sl.UseHook(l, ApiRoutesHook, api); err != nil {
return nil, err
}
go func() {
log.Fatal(r.Listen(cfg.Host))
}()
return &Server{r}, nil
}