package server import ( "context" "fmt" "time" fiberzap "github.com/gofiber/contrib/fiberzap/v2" "github.com/gofiber/contrib/swagger" "github.com/gofiber/fiber/v2" middleware "github.com/oapi-codegen/fiber-middleware" "go.uber.org/zap" ) type Server struct { port int logger *zap.Logger apiHandlers *APIHandlers } func NewServer(apiHandlers *APIHandlers, port int, logger *zap.Logger) *Server { return &Server{ apiHandlers: apiHandlers, port: port, logger: logger, } } func (s *Server) Run(ctx context.Context) { sugared := s.logger.Sugar() config := fiber.Config{ DisableStartupMessage: true, IdleTimeout: 10 * time.Second, ReadTimeout: 10 * time.Second, WriteTimeout: 10 * time.Second, } app := fiber.New(config) app.Use(fiberzap.New(fiberzap.Config{ Logger: s.logger, })) swaggerConfig := swagger.Config{ BasePath: "/", FilePath: "./api/v1/openapi.yaml", Path: "/swagger", Title: "Swagger API Docs", } app.Use(swagger.New(swaggerConfig)) swagger, err := GetSwagger() if err != nil { sugared.Fatal("Error getting swagger", zap.Error(err)) } // See: https://github.com/deepmap/oapi-codegen/blob/master/examples/petstore-expanded/fiber/petstore.go#L41 // Clear out the servers array in the swagger spec, that skips validating // that server names match. We don't know how this thing will be run. swagger.Servers = nil app.Use(middleware.OapiRequestValidator(swagger)) handlers := NewStrictHandler(s.apiHandlers, nil) RegisterHandlers(app, handlers) go func() { err := app.Listen(fmt.Sprintf(":%d", s.port)) if err != nil { panic(err) } }() sugared.Infow("HTTP server is now running", "port", s.port) <-ctx.Done() shutdownBegan := time.Now() sugared.Infoln("Shutting HTTP server down gracefully...") err = app.ShutdownWithTimeout(10 * time.Second) if err != nil { panic(err) } // Cleanup code here sugared.Infow("HTTP server shut down gracefully.", "took", time.Since(shutdownBegan)) }