mirror of
				https://github.com/3ybactuk/marketplace-go-service-project.git
				synced 2025-10-30 05:53:45 +03:00 
			
		
		
		
	
		
			
				
	
	
		
			105 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			105 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package app
 | |
| 
 | |
| import (
 | |
| 	"fmt"
 | |
| 	"net"
 | |
| 	"net/http"
 | |
| 	"os"
 | |
| 	"time"
 | |
| 
 | |
| 	"github.com/rs/zerolog"
 | |
| 	"github.com/rs/zerolog/log"
 | |
| 
 | |
| 	"route256/cart/internal/app/server"
 | |
| 	"route256/cart/internal/domain/cart/repository"
 | |
| 	"route256/cart/internal/domain/cart/service"
 | |
| 	product_service "route256/cart/internal/domain/products/service"
 | |
| 	"route256/cart/internal/infra/config"
 | |
| 	"route256/cart/internal/infra/http/middlewares"
 | |
| 	"route256/cart/internal/infra/http/round_trippers"
 | |
| )
 | |
| 
 | |
| const (
 | |
| 	productsRetryAttemptsDefault   = 3
 | |
| 	productsInitialDelaySecDefault = 1
 | |
| )
 | |
| 
 | |
| type App struct {
 | |
| 	config *config.Config
 | |
| 	server http.Server
 | |
| }
 | |
| 
 | |
| func NewApp(configPath string) (*App, error) {
 | |
| 	c, err := config.LoadConfig(configPath)
 | |
| 	if err != nil {
 | |
| 		return nil, fmt.Errorf("unable to load config: %w", err)
 | |
| 	}
 | |
| 
 | |
| 	log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr})
 | |
| 	zerolog.SetGlobalLevel(zerolog.InfoLevel)
 | |
| 
 | |
| 	if c.Service.LogLevel != "" {
 | |
| 		level, err := zerolog.ParseLevel(c.Service.LogLevel)
 | |
| 		if err != nil {
 | |
| 			return nil, fmt.Errorf("unknown log level `%s` provided: %w", c.Service.LogLevel, err)
 | |
| 		}
 | |
| 
 | |
| 		zerolog.SetGlobalLevel(level)
 | |
| 	}
 | |
| 
 | |
| 	log.WithLevel(zerolog.GlobalLevel()).Msgf("using logging level=`%s`", zerolog.GlobalLevel().String())
 | |
| 
 | |
| 	app := &App{
 | |
| 		config: c,
 | |
| 	}
 | |
| 	app.server.Handler = app.bootstrapHandlers()
 | |
| 
 | |
| 	return app, nil
 | |
| }
 | |
| 
 | |
| func (app *App) ListenAndServe() error {
 | |
| 	address := fmt.Sprintf("%s:%s", app.config.Service.Host, app.config.Service.Port)
 | |
| 
 | |
| 	l, err := net.Listen("tcp", address)
 | |
| 	if err != nil {
 | |
| 		return err
 | |
| 	}
 | |
| 
 | |
| 	log.Info().Msgf("Serving cart at http://%s", l.Addr())
 | |
| 
 | |
| 	return app.server.Serve(l)
 | |
| }
 | |
| 
 | |
| func (app *App) bootstrapHandlers() http.Handler {
 | |
| 	transport := http.DefaultTransport
 | |
| 	transport = round_trippers.NewLogRoundTripper(transport)
 | |
| 	transport = round_trippers.NewRetryRoundTripper(transport, productsRetryAttemptsDefault, productsInitialDelaySecDefault)
 | |
| 
 | |
| 	httpClient := http.Client{
 | |
| 		Transport: transport,
 | |
| 		Timeout:   10 * time.Second,
 | |
| 	}
 | |
| 
 | |
| 	productService := product_service.NewProductService(
 | |
| 		httpClient,
 | |
| 		app.config.ProductService.Token,
 | |
| 		fmt.Sprintf("%s:%s", app.config.ProductService.Host, app.config.ProductService.Port),
 | |
| 	)
 | |
| 
 | |
| 	const userCartCap = 100
 | |
| 	cartRepository := repository.NewInMemoryRepository(userCartCap)
 | |
| 	cartService := service.NewCartService(cartRepository, productService)
 | |
| 
 | |
| 	s := server.NewServer(cartService)
 | |
| 
 | |
| 	mx := http.NewServeMux()
 | |
| 	mx.HandleFunc("POST /user/{user_id}/cart/{sku_id}", s.AddItemHandler)
 | |
| 	mx.HandleFunc("GET /user/{user_id}/cart", s.GetItemsByUserIDHandler)
 | |
| 	mx.HandleFunc("DELETE /user/{user_id}/cart/{sku_id}", s.DeleteItemHandler)
 | |
| 	mx.HandleFunc("DELETE /user/{user_id}/cart", s.DeleteItemsByUserIDHandler)
 | |
| 
 | |
| 	h := middlewares.NewTimerMiddleware(mx)
 | |
| 
 | |
| 	return h
 | |
| }
 | 
