Files
payouts/internal/api/module.go

115 lines
3.0 KiB
Go

package api
import (
"context"
"fmt"
"log/slog"
"net/http"
"net/http/pprof"
"github.com/gorilla/mux"
"github.com/prometheus/client_golang/prometheus/promhttp"
"go.uber.org/fx"
"payouts/internal/api/health"
"payouts/internal/api/payout"
"payouts/internal/api/user"
"payouts/internal/api/version"
appConfig "payouts/internal/config"
"payouts/internal/service/monitoring"
)
// Module is a fx module
var Module = fx.Options(
user.Module,
health.Module,
payout.Module,
version.Module,
monitoring.Module,
fx.Invoke(RegisterRoutes),
)
const BaseRoute = "/api/v1"
// Params represents the module input params
type Params struct {
fx.In
Logger *slog.Logger
AppConfig *appConfig.App
PayoutHandler payout.Handler
UserHandler user.Handler
Version version.Handler
HealthHandler health.Handler
Metrics monitoring.Metrics
}
// RegisterRoutes registers the api routes and starts the http server
func RegisterRoutes(p Params, lc fx.Lifecycle) {
router := mux.NewRouter()
router.StrictSlash(true)
// Version endpoint
router.HandleFunc(version.Route, p.Version.VersionHandler).Methods(http.MethodGet)
// Health check endpoint
router.HandleFunc(health.Route, p.HealthHandler.Health).Methods(http.MethodGet)
if p.AppConfig.Server.EnablePProfEndpoints {
router.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline)
router.HandleFunc("/debug/pprof/profile", pprof.Profile)
router.HandleFunc("/debug/pprof/symbol", pprof.Symbol)
router.HandleFunc("/debug/pprof/trace", pprof.Trace)
router.NewRoute().PathPrefix("/debug/pprof/").HandlerFunc(pprof.Index)
}
apiRouter := router.PathPrefix(BaseRoute).Subrouter()
userRouter := apiRouter.PathPrefix(user.BaseRoute).Subrouter()
userRouter.HandleFunc(user.RegisterRoute, p.UserHandler.UserRegister).Methods(http.MethodPost)
userRouter.HandleFunc(user.LoginRoute, p.UserHandler.UserLogin).Methods(http.MethodPost)
payoutRouter := apiRouter.PathPrefix(payout.BaseRoute).Subrouter()
payoutRouter.HandleFunc(payout.BanksRoute, p.PayoutHandler.GetSbpBanks).Methods(http.MethodGet)
payoutRouter.HandleFunc(payout.CreateRoute, p.PayoutHandler.PayoutCreate).Methods(http.MethodPost)
payoutRouter.HandleFunc(payout.CallbackRoute, p.PayoutHandler.PayoutCallback).Methods(http.MethodPost)
// collect api metrics
apiRouter.Use(p.Metrics.GetMiddleware())
router.Handle(p.AppConfig.Metrics.Endpoint, promhttp.Handler())
srv := http.Server{
Handler: router,
Addr: p.AppConfig.Server.Port,
WriteTimeout: p.AppConfig.Server.WriteTimeout,
ReadTimeout: p.AppConfig.Server.ReadTimeout,
}
lc.Append(fx.Hook{
OnStart: func(c context.Context) error {
go func() {
var err error
slog.Info(fmt.Sprintf("Starting server on port %s", p.AppConfig.Server.Port))
if p.AppConfig.Server.Tls.Enabled {
err = srv.ListenAndServeTLS(p.AppConfig.Server.Tls.CertFile, p.AppConfig.Server.Tls.KeyFile)
} else {
err = srv.ListenAndServe()
}
if err != nil {
panic(err)
}
}()
return nil
},
OnStop: func(ctx context.Context) error {
return srv.Shutdown(ctx)
},
})
}