2022-01-29 18:43:07 +01:00

102 lines
2.0 KiB
Go

package api
import (
"context"
"log"
"math/rand"
"net/http"
"os"
"os/signal"
"time"
"github.com/gin-gonic/gin"
gomysql "github.com/go-sql-driver/mysql"
"gorm.io/gorm"
gormlogger "gorm.io/gorm/logger"
)
type Service struct {
Gin *gin.Engine
DB *gorm.DB
Config *ServiceConfig
Logger *log.Logger
GormLogger gormlogger.Interface
}
type ServiceConfig struct {
Listen string
Mysql *gomysql.Config
}
func New(logger *log.Logger, config *ServiceConfig) *Service {
return &Service{
Gin: gin.New(),
Config: config,
Logger: logger,
GormLogger: gormlogger.New(
log.New(os.Stdout, "\r\n", log.LstdFlags), // io writer
gormlogger.Config{
SlowThreshold: time.Second, // Slow SQL threshold
LogLevel: gormlogger.Error, // Log level
IgnoreRecordNotFoundError: true, // Ignore ErrRecordNotFound error for logger
Colorful: true, // Disable color
},
),
}
}
func (s *Service) SetupRoutes() {
s.Gin.Use(gin.Logger())
s.Gin.Use(s.Recovery)
s.Gin.NoRoute(func(c *gin.Context) {
c.JSON(http.StatusNotFound, gin.H{
"error": "this route doesn't exists",
})
})
}
func (s *Service) Run() error {
rand.Seed(time.Now().UnixNano())
s.SetupRoutes()
s.SetupDB()
srv := &http.Server{
Addr: s.Config.Listen,
Handler: s.Gin,
}
quit := make(chan os.Signal, 1)
var runError error
go func() {
// service connections
if runError = srv.ListenAndServe(); runError != nil {
quit <- os.Interrupt
}
}()
// Wait for interrupt signal to gracefully shutdown the server with
// a timeout of 5 seconds.
signal.Notify(quit, os.Interrupt)
<-quit
s.Logger.Println("shutdown ...")
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
if err := srv.Shutdown(ctx); err != nil {
return err
}
db, err := s.DB.DB()
if err != nil {
return err
}
s.Logger.Println("closing database ...")
if err := db.Close(); err != nil {
return err
}
s.Logger.Println("exiting")
return runError
}