From b1647e6d6c65839d80cae719690ef0caf8e1c719 Mon Sep 17 00:00:00 2001 From: Felix Fernando Wijaya Date: Sat, 8 Jun 2024 20:25:23 +0700 Subject: [PATCH 1/2] Add user routes and refactor --- cmd/main.go | 69 +++++++++++++------ internal/app/api/handler/handler.go | 26 +++++++ internal/app/api/router.go | 41 +++++++++++ internal/app/api/server.go | 26 +++++-- internal/app/interactor/interactor.go | 7 ++ .../auth.interface.go => ports/auth_ports.go} | 2 +- .../user.interface.go => ports/user_ports.go} | 11 ++- internal/app/repository/user.go | 4 +- internal/app/service/auth_service.go | 25 +++++++ internal/app/service/user_service.go | 1 + pkg/env/env.go | 2 +- pkg/logger/logger.go | 8 +-- 12 files changed, 185 insertions(+), 37 deletions(-) create mode 100644 internal/app/api/handler/handler.go create mode 100644 internal/app/api/router.go rename internal/app/{interfaces/auth.interface.go => ports/auth_ports.go} (57%) rename internal/app/{interfaces/user.interface.go => ports/user_ports.go} (52%) create mode 100644 internal/app/service/auth_service.go create mode 100644 internal/app/service/user_service.go diff --git a/cmd/main.go b/cmd/main.go index b8a2e04..b55b7a5 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -4,14 +4,16 @@ import ( "context" "os" "os/signal" - "runtime" "sync" "syscall" "github.com/voltgizerz/POS-restaurant/config" "github.com/voltgizerz/POS-restaurant/database" "github.com/voltgizerz/POS-restaurant/internal/app/api" + "github.com/voltgizerz/POS-restaurant/internal/app/api/handler" + "github.com/voltgizerz/POS-restaurant/internal/app/interactor" "github.com/voltgizerz/POS-restaurant/internal/app/repository" + "github.com/voltgizerz/POS-restaurant/internal/app/service" "github.com/voltgizerz/POS-restaurant/pkg/jeager" "github.com/voltgizerz/POS-restaurant/pkg/logger" ) @@ -24,39 +26,64 @@ func main() { cfg := config.NewConfig() defer handlePanic() - closer, err := jeager.NewJeager(cfg.App.Name) - if err != nil { - logger.LogStdErr.Errorf("[NewJeager] Error initializing Jaeger: %v\n", err) - } - defer closer.Close() + // Initialize Jaeger + initJaeger(cfg.App.Name) - ctx := context.Background() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() - // Init database + // Initialize database db := database.InitDatabase(ctx, cfg.Database) - repositoryOpts := repository.RepositoryOpts{ + repoOpts := repository.RepositoryOpts{ Database: db, } - _ = repository.NewUserRepository(repositoryOpts) + // Initialize Repositories + userRepo := repository.NewUserRepository(repoOpts) + + // Initialize Services + userService := service.NewUserService(userRepo) - // Init API - go api.NewServer(cfg.API) + // Initialize Handlers + userHandler := handler.NewUserHandler(userService) - // Wait for a termination signal - sc := make(chan os.Signal, 1) - signal.Notify(sc, syscall.SIGINT, syscall.SIGTERM, os.Interrupt) - <-sc + interactoAPI := interactor.APInteractor{ + Cfg: cfg.API, + UserHandler: userHandler, + } + + // Start API server + go startAPIServer(interactoAPI) + + // Wait for termination signal + waitForSignal() +} - logger.LogStdOut.Warnln("Application is exiting. Graceful shutdown in action...") +func initJaeger(serviceName string) { + closer, err := jeager.NewJeager(serviceName) + if err != nil { + logger.LogStdErr.Errorf("[NewJeager] Error initializing Jaeger: %v", err) + return + } + defer closer.Close() } func handlePanic() { if r := recover(); r != nil { - // Log panic location - stack := make([]byte, 4096) - runtime.Stack(stack, false) - logger.LogStdErr.WithField("panic", r).WithField("stack_trace", string(stack)).Error("Panic occurred!") + logger.LogStdErr.Errorf("Panic occurred: %v", r) } } + +func startAPIServer(interactor interactor.APInteractor) { + httpServer := api.NewServer(interactor) + httpServer.Initialize() +} + +func waitForSignal() { + sigCh := make(chan os.Signal, 1) + signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM) + <-sigCh + + logger.Log.Warnln("Application is exiting. Graceful shutdown in action...") +} diff --git a/internal/app/api/handler/handler.go b/internal/app/api/handler/handler.go new file mode 100644 index 0000000..7ed7b36 --- /dev/null +++ b/internal/app/api/handler/handler.go @@ -0,0 +1,26 @@ +package handler + +import ( + "github.com/gofiber/fiber/v3" + "github.com/voltgizerz/POS-restaurant/internal/app/ports" +) + +type UserHandler struct { + userService ports.IUserService +} + +func NewUserHandler(userService ports.IUserService) *UserHandler { + return &UserHandler{ + userService: userService, + } +} + +func (h *UserHandler) Login(c fiber.Ctx) error { + // TODO + return nil +} + +func (h *UserHandler) Register(c fiber.Ctx) error { + // TODO + return nil +} diff --git a/internal/app/api/router.go b/internal/app/api/router.go new file mode 100644 index 0000000..35d0576 --- /dev/null +++ b/internal/app/api/router.go @@ -0,0 +1,41 @@ +package api + +import ( + "github.com/gofiber/fiber/v3" + "github.com/voltgizerz/POS-restaurant/pkg/logger" +) + +// InitRouter initializes routes for the API server. +func (s *Server) InitRouter() *fiber.App { + app := fiber.New() + + v1 := app.Group("api/v1") + s.initUserRoutes(v1) + s.initPingRoute(v1) + + // Print all routes when server starts + printRoutes(app) + + return app +} + +// initUserRoutes initializes user-related routes. +func (s *Server) initUserRoutes(group fiber.Router) { + userRoutes := group.Group("/user") + userRoutes.Post("/login", s.userHandler.Login) + userRoutes.Post("/register", s.userHandler.Register) +} + +// initPingRoute initializes the ping route. +func (s *Server) initPingRoute(group fiber.Router) { + group.Get("/ping", func(c fiber.Ctx) error { + return c.SendString("Pong") + }) +} + +// printRoutes prints all registered routes. +func printRoutes(app *fiber.App) { + for _, route := range app.GetRoutes() { + logger.Log.Infof("[%s] %s", route.Method, route.Path) + } +} diff --git a/internal/app/api/server.go b/internal/app/api/server.go index 33e69f7..1047f6d 100644 --- a/internal/app/api/server.go +++ b/internal/app/api/server.go @@ -1,17 +1,29 @@ package api import ( - "github.com/gofiber/fiber/v3" "github.com/voltgizerz/POS-restaurant/config" + "github.com/voltgizerz/POS-restaurant/internal/app/interactor" + "github.com/voltgizerz/POS-restaurant/internal/app/ports" "github.com/voltgizerz/POS-restaurant/pkg/logger" ) -func NewServer(cfg config.API) { - app := fiber.New() +type Server struct { + cfg config.API + userHandler ports.IUserHandler +} + +func NewServer(interactor interactor.APInteractor) *Server { + return &Server{ + cfg: interactor.Cfg, + userHandler: interactor.UserHandler, + } +} - app.Get("/ping", func(c fiber.Ctx) error { - return c.SendString("pong") - }) +func (s *Server) Initialize() { + app := s.InitRouter() - logger.LogStdErr.Fatal(app.Listen(":" + cfg.PORT)) + err := app.Listen(":" + s.cfg.PORT) + if err != nil { + logger.LogStdErr.Fatalf("[Initialize] error on: %s", err.Error()) + } } diff --git a/internal/app/interactor/interactor.go b/internal/app/interactor/interactor.go index c12d8b3..bfa313f 100644 --- a/internal/app/interactor/interactor.go +++ b/internal/app/interactor/interactor.go @@ -1,4 +1,11 @@ package interactor +import ( + "github.com/voltgizerz/POS-restaurant/config" + "github.com/voltgizerz/POS-restaurant/internal/app/ports" +) + type APInteractor struct { + Cfg config.API + UserHandler ports.IUserHandler } diff --git a/internal/app/interfaces/auth.interface.go b/internal/app/ports/auth_ports.go similarity index 57% rename from internal/app/interfaces/auth.interface.go rename to internal/app/ports/auth_ports.go index c8865d1..a43ddd5 100644 --- a/internal/app/interfaces/auth.interface.go +++ b/internal/app/ports/auth_ports.go @@ -1,4 +1,4 @@ -package interfaces +package ports type IAuth interface { } diff --git a/internal/app/interfaces/user.interface.go b/internal/app/ports/user_ports.go similarity index 52% rename from internal/app/interfaces/user.interface.go rename to internal/app/ports/user_ports.go index 697743a..5ef0d84 100644 --- a/internal/app/interfaces/user.interface.go +++ b/internal/app/ports/user_ports.go @@ -1,11 +1,20 @@ -package interfaces +package ports import ( "context" + "github.com/gofiber/fiber/v3" "github.com/voltgizerz/POS-restaurant/internal/app/entity" ) type IUserRepository interface { GetUser(ctx context.Context, int64 int64) (*entity.User, error) } + +type IUserService interface { +} + +type IUserHandler interface { + Login(c fiber.Ctx) error + Register(c fiber.Ctx) error +} diff --git a/internal/app/repository/user.go b/internal/app/repository/user.go index 76c35f5..0f0f1fc 100644 --- a/internal/app/repository/user.go +++ b/internal/app/repository/user.go @@ -7,7 +7,7 @@ import ( "github.com/opentracing/opentracing-go" "github.com/sirupsen/logrus" "github.com/voltgizerz/POS-restaurant/internal/app/entity" - "github.com/voltgizerz/POS-restaurant/internal/app/interfaces" + "github.com/voltgizerz/POS-restaurant/internal/app/ports" "github.com/voltgizerz/POS-restaurant/pkg/logger" ) @@ -15,7 +15,7 @@ type UserRepository struct { MasterDB *sqlx.DB } -func NewUserRepository(opts RepositoryOpts) interfaces.IUserRepository { +func NewUserRepository(opts RepositoryOpts) ports.IUserRepository { return &UserRepository{ MasterDB: opts.Database.MasterDB, } diff --git a/internal/app/service/auth_service.go b/internal/app/service/auth_service.go new file mode 100644 index 0000000..1364680 --- /dev/null +++ b/internal/app/service/auth_service.go @@ -0,0 +1,25 @@ +package service + +import ( + "github.com/voltgizerz/POS-restaurant/internal/app/ports" +) + +type UserService struct { + userRepository ports.IUserRepository +} + +func NewUserService(repository ports.IUserRepository) *UserService { + return &UserService{ + userRepository: repository, + } +} + +func (s *UserService) Login(email string, password string) error { + // TODO + return nil +} + +func (s *UserService) Register(email string, password string, confirmPass string) error { + // TODO + return nil +} diff --git a/internal/app/service/user_service.go b/internal/app/service/user_service.go new file mode 100644 index 0000000..2e5a6c3 --- /dev/null +++ b/internal/app/service/user_service.go @@ -0,0 +1 @@ +package service \ No newline at end of file diff --git a/pkg/env/env.go b/pkg/env/env.go index f99175a..a1f76e2 100644 --- a/pkg/env/env.go +++ b/pkg/env/env.go @@ -14,7 +14,7 @@ const ( // LoadENV - load env file. func LoadENV() { if err := godotenv.Load(); err != nil { - logger.LogStdOut.Warn("No .env file found") + logger.Log.Warn("No .env file found") } } diff --git a/pkg/logger/logger.go b/pkg/logger/logger.go index bf7b0db..789e485 100644 --- a/pkg/logger/logger.go +++ b/pkg/logger/logger.go @@ -11,19 +11,19 @@ import ( // //revive:disable:import-shadowing var ( - LogStdOut *logrus.Logger + Log *logrus.Logger LogStdErr *logrus.Logger ) func Init() { logStdOut := logrus.New() - logStdOut.SetOutput(os.Stdout) - logStdOut.SetFormatter(&nested.Formatter{ + Log.SetOutput(os.Stdout) + Log.SetFormatter(&nested.Formatter{ TimestampFormat: "Jan 02 03:04:05.000 PM", HideKeys: false, FieldsOrder: []string{"component", "category"}, }) - LogStdOut = logStdOut + Log = logStdOut logStdErr := logrus.New() logStdErr.SetOutput(os.Stderr) From 8fdeedd70e662d5e4939ef3619e5f4d5576acb29 Mon Sep 17 00:00:00 2001 From: Felix Fernando Wijaya Date: Sat, 8 Jun 2024 20:27:02 +0700 Subject: [PATCH 2/2] Fix error log --- pkg/logger/logger.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/logger/logger.go b/pkg/logger/logger.go index 789e485..899b54e 100644 --- a/pkg/logger/logger.go +++ b/pkg/logger/logger.go @@ -17,8 +17,8 @@ var ( func Init() { logStdOut := logrus.New() - Log.SetOutput(os.Stdout) - Log.SetFormatter(&nested.Formatter{ + logStdOut.SetOutput(os.Stdout) + logStdOut.SetFormatter(&nested.Formatter{ TimestampFormat: "Jan 02 03:04:05.000 PM", HideKeys: false, FieldsOrder: []string{"component", "category"},