From 4ad9199a651b5ff91757945afde566cdfaa9e7fa Mon Sep 17 00:00:00 2001 From: mzfarshad Date: Sun, 12 Apr 2026 23:34:27 +0330 Subject: [PATCH] implemented echo server instance in pkg directory --- pkg/httpserver/constant.go | 7 ++++ pkg/httpserver/server.go | 83 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+) create mode 100644 pkg/httpserver/constant.go create mode 100644 pkg/httpserver/server.go diff --git a/pkg/httpserver/constant.go b/pkg/httpserver/constant.go new file mode 100644 index 00000000..30be3c74 --- /dev/null +++ b/pkg/httpserver/constant.go @@ -0,0 +1,7 @@ +package httpserver + +import "time" + +const ( + DefaultShutdownTimeout = 10 * time.Second +) diff --git a/pkg/httpserver/server.go b/pkg/httpserver/server.go new file mode 100644 index 00000000..05e9867f --- /dev/null +++ b/pkg/httpserver/server.go @@ -0,0 +1,83 @@ +package httpserver + +import ( + "context" + "fmt" + "github.com/labstack/echo/v4" + "github.com/labstack/echo/v4/middleware" + "time" +) + +type Config struct { + Host string `koanf:"host"` + Port int `koanf:"port"` + CORS CORS `koanf:"cors"` + ShutdownTimeout time.Duration `koanf:"shutdown_context_timeout"` + HideBanner bool `koanf:"hide_banner"` + HidePort bool `koanf:"hide_port"` + + // Optional Otel middleware can be injected from outside. + OtelMiddleware echo.MiddlewareFunc +} + +type CORS struct { + AllowOrigins []string `koanf:"allow_origins"` +} + +type Server struct { + router *echo.Echo + config *Config +} + +func New(cfg Config) (*Server, error) { + if cfg.Port < 1 || cfg.Port > 65535 { + return nil, fmt.Errorf("invalid port: %d", cfg.Port) + } + + if cfg.ShutdownTimeout <= 0 { + cfg.ShutdownTimeout = DefaultShutdownTimeout + } + + e := echo.New() + + if cfg.OtelMiddleware != nil { + e.Use(cfg.OtelMiddleware) + } + + e.Use(middleware.RequestID()) + e.Use(middleware.Logger()) + e.Use(middleware.Recover()) + e.Use( + middleware.CORSWithConfig( + middleware.CORSConfig{ + AllowOrigins: cfg.CORS.AllowOrigins, + }, + ), + ) + + return &Server{ + router: e, + config: &cfg, + }, nil +} + +func (s *Server) GetRouter() *echo.Echo { + return s.router +} + +func (s *Server) GetConfig() *Config { + return s.config +} + +func (s *Server) Start() error { + addr := fmt.Sprintf("%s:%d", s.config.Host, s.config.Port) + + s.router.HideBanner = s.config.HideBanner + s.router.HidePort = s.config.HidePort + + return s.router.Start(addr) +} + +func (s *Server) Stop(ctx context.Context) error { + return s.router.Shutdown(ctx) +}