github.com/tuingking/flamingo@v0.0.0-20220403134817-2796ae0e84ca/cmd/rest/main.go (about)

     1  package main
     2  
     3  import (
     4  	"context"
     5  	"html/template"
     6  	"net/http"
     7  	"os"
     8  	"os/signal"
     9  	"runtime"
    10  	"syscall"
    11  	"time"
    12  
    13  	"github.com/pkg/errors"
    14  	"github.com/tuingking/flamingo/config"
    15  	"github.com/tuingking/flamingo/handler/rest"
    16  	"github.com/tuingking/flamingo/infra/httpserver"
    17  	"github.com/tuingking/flamingo/infra/logger"
    18  	"github.com/tuingking/flamingo/infra/mysql"
    19  	"github.com/tuingking/flamingo/internal/account"
    20  	"github.com/tuingking/flamingo/internal/auth"
    21  	"github.com/tuingking/flamingo/internal/product"
    22  )
    23  
    24  var (
    25  	Namespace    string
    26  	BuildVersion string
    27  	BuildTime    string
    28  	CommitHash   string
    29  )
    30  
    31  // @title Swagger Flamingo API
    32  // @version 1.0
    33  // @description This is a sample server Petstore server.
    34  // @termsOfService http://swagger.io/terms/
    35  
    36  // @contact.name API Support
    37  // @contact.url http://www.swagger.io/support
    38  // @contact.email support@swagger.io
    39  
    40  // @license.name Apache 2.0
    41  // @license.url http://www.apache.org/licenses/LICENSE-2.0.html
    42  
    43  // @host localhost:8080
    44  // @BasePath /api
    45  func main() {
    46  	meta := config.Metadata{
    47  		Namespace:    Namespace,
    48  		GoVersion:    runtime.Version(),
    49  		BuildVersion: BuildVersion,
    50  		BuildTime:    BuildTime,
    51  		CommitHash:   CommitHash,
    52  	}
    53  
    54  	// config
    55  	cfg := config.Init(
    56  		config.WithConfigFile("config"),
    57  		config.WithConfigType("yaml"),
    58  	)
    59  	cfg.SetMetadata(meta)
    60  
    61  	// Infra
    62  	logger := logger.New(cfg.Logger)
    63  	sql := mysql.New(cfg.MySQL)
    64  
    65  	logger.Infof("Meta: %+v", cfg.Meta)
    66  	logger.Infof("MySQL: %+v", cfg.MySQL)
    67  
    68  	// Auth
    69  	authSvc := auth.NewService(cfg.Auth, logger)
    70  	// Account
    71  	accountRepo := account.NewRepository(sql)
    72  	accountSvc := account.NewService(cfg.Account, logger, accountRepo)
    73  	// Product
    74  	productRepo := product.NewRepository(sql)
    75  	productSvc := product.NewService(cfg.Product.Service, logger, productRepo)
    76  
    77  	// web template
    78  	tpl := template.Must(template.ParseGlob("web/templates/*"))
    79  
    80  	// rest handler
    81  	restHandler := rest.NewRestHandler(
    82  		logger,
    83  		tpl,
    84  		authSvc,
    85  		productSvc,
    86  		accountSvc,
    87  	)
    88  
    89  	// http handler
    90  	mux := rest.NewHttpHandler(restHandler)
    91  
    92  	// server
    93  	server := httpserver.New(cfg.HttpServer, logger, mux)
    94  
    95  	// graceful shutdown
    96  	go func() {
    97  		quit := make(chan os.Signal, 1)
    98  		signal.Notify(quit, os.Interrupt, syscall.SIGTERM)
    99  
   100  		// waiting for os signal
   101  		<-quit
   102  
   103  		ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
   104  		defer cancel()
   105  
   106  		if err := server.Shutdown(ctx); err != nil {
   107  			logger.Error(errors.Wrap(err, "failed to shutdown server"))
   108  		}
   109  		logger.Info("server shutdown gracefully 😁")
   110  	}()
   111  
   112  	// serve
   113  	if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
   114  		logger.Fatal(errors.Wrap(err, "ListenAndServe"))
   115  	}
   116  
   117  	logger.Info("bye bye 👋👋")
   118  }