mirror of
https://forgejo.merr.is/annika/isl-api.git
synced 2025-12-10 11:53:14 -05:00
120 lines
3.2 KiB
Go
120 lines
3.2 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"log/slog"
|
|
"net/http"
|
|
"os"
|
|
"time"
|
|
|
|
"forgejo.merr.is/annika/isl-api/controllers"
|
|
"forgejo.merr.is/annika/isl-api/middlewares"
|
|
"forgejo.merr.is/annika/isl-api/routes"
|
|
"forgejo.merr.is/annika/isl-api/services"
|
|
"forgejo.merr.is/annika/isl-api/sql/powerItem"
|
|
"github.com/go-chi/chi/v5"
|
|
"github.com/go-chi/cors"
|
|
"github.com/go-chi/httplog/v2"
|
|
"github.com/jackc/pgx/v4/pgxpool"
|
|
"github.com/lmittmann/tint"
|
|
"github.com/spf13/viper"
|
|
)
|
|
|
|
var conf *EnvConfigs
|
|
var logger *slog.Logger
|
|
|
|
func init() {
|
|
w := os.Stderr
|
|
logger = slog.New(
|
|
tint.NewHandler(w, &tint.Options{
|
|
TimeFormat: time.RFC3339Nano,
|
|
}),
|
|
)
|
|
logger.Info("Initializing isl-api")
|
|
setupConfig()
|
|
logger = slog.New(
|
|
tint.NewHandler(w, &tint.Options{
|
|
Level: conf.GetLogLevel(),
|
|
TimeFormat: time.RFC3339Nano,
|
|
}),
|
|
)
|
|
}
|
|
|
|
func main() {
|
|
logger.Info("Starting isl-api")
|
|
deps := dependencies{}
|
|
deps.initializeDependencies()
|
|
|
|
logger.Info(fmt.Sprintf("Preparing to listen on `:%v`", conf.HttpPort))
|
|
err := http.ListenAndServe(fmt.Sprintf(":%v", conf.HttpPort), deps.router)
|
|
logger.Error("Error starting server", "error", err)
|
|
}
|
|
|
|
func setupConfig() {
|
|
logger.Info("Loading config")
|
|
viper.AddConfigPath(".")
|
|
viper.SetConfigName(".env")
|
|
viper.SetConfigType("env")
|
|
|
|
viper.SetEnvPrefix("isl_api")
|
|
viper.AutomaticEnv()
|
|
|
|
if err := viper.ReadInConfig(); err != nil {
|
|
logger.Error("Error reading env file, exiting", "error", err)
|
|
panic(err)
|
|
}
|
|
|
|
if err := viper.Unmarshal(&conf); err != nil {
|
|
logger.Error("Unable to unmarshal configuration, exiting", "error", err)
|
|
panic(err)
|
|
}
|
|
logger.Info("Finished loading config")
|
|
}
|
|
|
|
type dependencies struct {
|
|
router *chi.Mux
|
|
postgresConnection *pgxpool.Pool
|
|
context context.Context
|
|
powerItemQuerier *powerItem.DBQuerier
|
|
powerItemService *services.PowerItemService
|
|
powerItemController *controllers.PowerItemController
|
|
}
|
|
|
|
func (d *dependencies) initializeDependencies() error {
|
|
logger.Info("Initializing dependencies")
|
|
var err error
|
|
|
|
d.router = chi.NewRouter()
|
|
|
|
httpLogger := httplog.NewLogger("isl-api", httplog.Options{
|
|
Concise: true,
|
|
RequestHeaders: true,
|
|
})
|
|
httpLogger.Logger = logger
|
|
d.router.Use(httplog.RequestLogger(httpLogger))
|
|
|
|
d.router.Use(cors.Handler(cors.Options{
|
|
AllowedOrigins: []string{"*"},
|
|
AllowedMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"},
|
|
AllowedHeaders: []string{"Cache-Control", "Expires", "Pragma"},
|
|
}))
|
|
d.context = context.Background()
|
|
d.postgresConnection, err = pgxpool.Connect(d.context, conf.ConnectionString)
|
|
if err != nil {
|
|
logger.Error("Error setting up database connection", "error", err)
|
|
return err
|
|
}
|
|
d.powerItemQuerier = powerItem.NewQuerier(d.postgresConnection)
|
|
d.powerItemService = services.NewPowerItemService(d.powerItemQuerier)
|
|
d.powerItemController = controllers.NewPowerItemController(d.powerItemService)
|
|
|
|
tokenAuth, err := middlewares.New(conf.JWKSURI, d.context)
|
|
if err != nil {
|
|
logger.Error("Error setting up JWT authentication middleware", "error", err)
|
|
}
|
|
|
|
d.router.Mount("/powerItems", routes.SetupPowerItemRoutes(*d.powerItemController, tokenAuth))
|
|
logger.Info("Finished initializing dependencies")
|
|
return nil
|
|
}
|