Skip to content

Commit 7ea416f

Browse files
author
Mike Heffner
authored
Merge pull request #108 from netlify/feature/server-api
API lifecycle support
2 parents aa957b4 + 1c7412d commit 7ea416f

File tree

2 files changed

+47
-17
lines changed

2 files changed

+47
-17
lines changed

server/server.go

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"fmt"
66
"net/http"
7+
"net/http/httptest"
78
"time"
89

910
"github.com/netlify/netlify-commons/nconf"
@@ -17,6 +18,7 @@ import (
1718
type Server struct {
1819
log logrus.FieldLogger
1920
svr *http.Server
21+
api APIDefinition
2022
}
2123

2224
type Config struct {
@@ -25,9 +27,10 @@ type Config struct {
2527
TLS nconf.TLSConfig
2628
}
2729

28-
// APIDefinition is used to define the routes used by the API
30+
// APIDefinition is used to control lifecycle of the API
2931
type APIDefinition interface {
30-
AddRoutes(r router.Router)
32+
Start(r router.Router) error
33+
Stop()
3134
}
3235

3336
func New(log logrus.FieldLogger, projectName string, config Config, api APIDefinition) (*Server, error) {
@@ -37,14 +40,17 @@ func New(log logrus.FieldLogger, projectName string, config Config, api APIDefin
3740
router.OptTracingMiddleware(log, projectName),
3841
)
3942

40-
api.AddRoutes(r)
43+
if err := api.Start(r); err != nil {
44+
return nil, errors.Wrap(err, "Failed to start API")
45+
}
4146

4247
s := Server{
4348
log: log.WithField("component", "server"),
4449
svr: &http.Server{
4550
Addr: fmt.Sprintf(":%d", config.Port),
4651
Handler: r,
4752
},
53+
api: api,
4854
}
4955

5056
if config.TLS.Enabled {
@@ -77,20 +83,40 @@ func (s *Server) ListenAndServe() error {
7783
} else {
7884
err = s.svr.ListenAndServe()
7985
}
86+
87+
// Now that server is no longer listening, shutdown the API
88+
s.log.Info("Listener shutdown, stopping API")
89+
90+
s.api.Stop()
91+
92+
s.log.Debug("Completed shutting down the underlying API")
93+
8094
if err == http.ErrServerClosed {
8195
return nil
8296
}
8397
return err
8498
}
8599

100+
func (s *Server) TestServer() *httptest.Server {
101+
return httptest.NewServer(s.svr.Handler)
102+
}
103+
86104
type apiFunc struct {
87-
f func(router.Router)
105+
start func(router.Router) error
106+
stop func()
88107
}
89108

90-
func (a apiFunc) AddRoutes(r router.Router) {
91-
a.f(r)
109+
func (a apiFunc) Start(r router.Router) error {
110+
return a.start(r)
92111
}
93112

94-
func APIFunc(f func(router.Router)) APIDefinition {
95-
return apiFunc{f}
113+
func (a apiFunc) Stop() {
114+
a.stop()
115+
}
116+
117+
func APIFunc(start func(router.Router) error, stop func()) APIDefinition {
118+
return apiFunc{
119+
start: start,
120+
stop: stop,
121+
}
96122
}

server/server_test.go

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
11
package server
22

33
import (
4+
"github.com/netlify/netlify-commons/router"
5+
"github.com/sirupsen/logrus"
6+
"github.com/stretchr/testify/assert"
7+
"github.com/stretchr/testify/require"
48
"net/http"
59
"net/http/httptest"
610
"os"
711
"strings"
812
"testing"
9-
10-
"github.com/netlify/netlify-commons/router"
11-
"github.com/sirupsen/logrus"
12-
"github.com/stretchr/testify/assert"
13-
"github.com/stretchr/testify/require"
1413
)
1514

1615
func init() {
@@ -20,11 +19,16 @@ func init() {
2019
}
2120

2221
func TestServerHealth(t *testing.T) {
23-
apiDef := APIFunc(func(r router.Router) {
24-
r.Get("/", func(w http.ResponseWriter, r *http.Request) *router.HTTPError {
22+
apiDef := APIFunc(
23+
func(r router.Router) error {
24+
r.Get("/", func(w http.ResponseWriter, r *http.Request) *router.HTTPError {
25+
return nil
26+
})
2527
return nil
26-
})
27-
})
28+
},
29+
func() {
30+
},
31+
)
2832

2933
cfg := testConfig()
3034
svr, err := New(tl(t), "testing", cfg, apiDef)

0 commit comments

Comments
 (0)