github.com/dhax/go-base@v0.0.0-20231004214136-8be7e5c1972b/api/server.go (about)

     1  package api
     2  
     3  import (
     4  	"context"
     5  	"log"
     6  	"net/http"
     7  	"os"
     8  	"os/signal"
     9  	"strings"
    10  
    11  	"github.com/spf13/viper"
    12  )
    13  
    14  // Server provides an http.Server.
    15  type Server struct {
    16  	*http.Server
    17  }
    18  
    19  // NewServer creates and configures an APIServer serving all application routes.
    20  func NewServer() (*Server, error) {
    21  	log.Println("configuring server...")
    22  	api, err := New(viper.GetBool("enable_cors"))
    23  	if err != nil {
    24  		return nil, err
    25  	}
    26  
    27  	var addr string
    28  	port := viper.GetString("port")
    29  
    30  	// allow port to be set as localhost:3000 in env during development to avoid "accept incoming network connection" request on restarts
    31  	if strings.Contains(port, ":") {
    32  		addr = port
    33  	} else {
    34  		addr = ":" + port
    35  	}
    36  
    37  	srv := http.Server{
    38  		Addr:    addr,
    39  		Handler: api,
    40  	}
    41  
    42  	return &Server{&srv}, nil
    43  }
    44  
    45  // Start runs ListenAndServe on the http.Server with graceful shutdown.
    46  func (srv *Server) Start() {
    47  	log.Println("starting server...")
    48  	go func() {
    49  		if err := srv.ListenAndServe(); err != http.ErrServerClosed {
    50  			panic(err)
    51  		}
    52  	}()
    53  	log.Printf("Listening on %s\n", srv.Addr)
    54  
    55  	quit := make(chan os.Signal)
    56  	signal.Notify(quit, os.Interrupt)
    57  	sig := <-quit
    58  	log.Println("Shutting down server... Reason:", sig)
    59  	// teardown logic...
    60  
    61  	if err := srv.Shutdown(context.Background()); err != nil {
    62  		panic(err)
    63  	}
    64  	log.Println("Server gracefully stopped")
    65  }