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 }