Skip to content

Commit 73a66a2

Browse files
committed
refactor: merge http/router and http/server packages
Signed-off-by: Jörg Jooss <[email protected]>
1 parent 85880a0 commit 73a66a2

File tree

9 files changed

+67
-37
lines changed

9 files changed

+67
-37
lines changed

booklibrary/cmd/booklibrary-api/main.go

Lines changed: 46 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,19 @@ package main
33
import (
44
"context"
55
"flag"
6-
"fmt"
76
"net/http"
87
"os"
8+
"os/signal"
99
"runtime"
10+
"syscall"
1011
"time"
1112

1213
"log/slog"
1314

1415
"github.com/joergjo/go-samples/booklibrary/internal/config"
15-
"github.com/joergjo/go-samples/booklibrary/internal/http/router"
16-
"github.com/joergjo/go-samples/booklibrary/internal/http/server"
1716
"github.com/joergjo/go-samples/booklibrary/internal/log"
1817
"github.com/joergjo/go-samples/booklibrary/internal/mongo"
18+
"github.com/joergjo/go-samples/booklibrary/internal/webapi"
1919
)
2020

2121
var (
@@ -34,12 +34,17 @@ func main() {
3434
slog.Warn("debug logging enabled")
3535
}
3636

37+
os.Exit(run(s))
38+
}
39+
40+
func run(s config.Settings) int {
3741
crud, err := newCrudService(s.MongoURI, s.Db, s.Collection)
3842
if err != nil {
3943
slog.Error("creating book service", log.ErrorKey, err)
40-
os.Exit(1)
44+
return 1
4145
}
4246
defer func() {
47+
slog.Info("closing database connection")
4348
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
4449
defer cancel()
4550
if err := crud.Close(ctx); err != nil {
@@ -49,19 +54,41 @@ func main() {
4954
}
5055
}()
5156

52-
mux := router.NewMux(crud)
53-
srv := server.New(mux, s.Port)
54-
done := make(chan struct{})
55-
go server.Shutdown(context.Background(), srv, done)
57+
srv := webapi.NewServer(crud, s.Port)
58+
59+
errC := make(chan error, 1)
60+
go func() {
61+
slog.Info("starting server", log.AddrKey, srv.Addr)
62+
if err := srv.ListenAndServe(); err != http.ErrServerClosed {
63+
errC <- err
64+
}
65+
}()
66+
67+
sigC := make(chan os.Signal, 1)
68+
signal.Notify(sigC, syscall.SIGINT, syscall.SIGTERM)
5669

57-
slog.Info(fmt.Sprintf("server starting, listening on 0.0.0.0:%d", s.Port))
58-
if err = srv.ListenAndServe(); err != http.ErrServerClosed {
70+
var exit int
71+
select {
72+
case err := <-errC:
5973
slog.Error("server error", log.ErrorKey, err)
60-
os.Exit(1)
74+
exit = 1
75+
case sig := <-sigC:
76+
slog.Warn("received signal, shutting down", "signal", sig.String())
77+
78+
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
79+
defer cancel()
80+
81+
slog.Info("waiting for server to shut down")
82+
if err := srv.Shutdown(ctx); err != nil {
83+
slog.Error("shutting down server", "error", err)
84+
if err := srv.Close(); err != nil {
85+
slog.Error("forcefully closing server", "error", err)
86+
}
87+
}
88+
slog.Info("server has shut down")
6189
}
62-
slog.Info("waiting for shut down to complete")
63-
<-done
64-
slog.Info("server has shut down")
90+
91+
return exit
6592
}
6693

6794
func configure() config.Settings {
@@ -72,11 +99,11 @@ func configure() config.Settings {
7299
coll := config.GetEnvString("BOOKLIBRARY_COLLECTION", "books")
73100
debug := config.GetEnvBool("BOOKLIBRARY_DEBUG", false)
74101

75-
flag.IntVar(&(s.Port), "port", port, "HTTP port to listen on")
76-
flag.StringVar(&(s.MongoURI), "mongoURI", mongoURI, "MongoDB URI to connect to")
77-
flag.StringVar(&(s.Db), "db", db, "MongoDB database")
78-
flag.StringVar(&(s.Collection), "collection", coll, "MongoDB collection")
79-
flag.BoolVar(&(s.Debug), "debug", debug, "Enable debug logging")
102+
flag.IntVar(&s.Port, "port", port, "HTTP port to listen on")
103+
flag.StringVar(&s.MongoURI, "mongoURI", mongoURI, "MongoDB URI to connect to")
104+
flag.StringVar(&s.Db, "db", db, "MongoDB database")
105+
flag.StringVar(&s.Collection, "collection", coll, "MongoDB collection")
106+
flag.BoolVar(&s.Debug, "debug", debug, "Enable debug logging")
80107
flag.Parse()
81108
return s
82109
}

booklibrary/internal/log/keys.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@ const (
44
ErrorKey = "error"
55
IdKey = "id"
66
MongoURIKey = "mongoURI"
7+
AddrKey = "addr"
78
)

booklibrary/internal/http/router/json.go renamed to booklibrary/internal/webapi/json.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package router
1+
package webapi
22

33
import (
44
"encoding/json"

booklibrary/internal/http/router/metrics.go renamed to booklibrary/internal/webapi/metrics.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package router
1+
package webapi
22

33
import (
44
"net/http"

booklibrary/internal/http/router/mux.go renamed to booklibrary/internal/webapi/mux.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package router
1+
package webapi
22

33
import (
44
"context"

booklibrary/internal/http/router/mux_test.go renamed to booklibrary/internal/webapi/mux_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
package router_test
1+
package webapi_test
22

33
import (
44
"context"
55
"net/http"
66
"net/http/httptest"
77
"testing"
88

9-
"github.com/joergjo/go-samples/booklibrary/internal/http/router"
109
"github.com/joergjo/go-samples/booklibrary/internal/model"
10+
"github.com/joergjo/go-samples/booklibrary/internal/webapi"
1111
)
1212

1313
func TestSystemEndpoints(t *testing.T) {
@@ -38,7 +38,7 @@ func TestSystemEndpoints(t *testing.T) {
3838
crud.GetFn = func(_ context.Context, id string) (model.Book, error) {
3939
return model.Book{}, nil
4040
}
41-
router := router.NewMux(&crud)
41+
router := webapi.NewMux(&crud)
4242
ts := httptest.NewServer(router)
4343
defer ts.Close()
4444

booklibrary/internal/http/router/resource.go renamed to booklibrary/internal/webapi/resource.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package router
1+
package webapi
22

33
import (
44
"errors"

booklibrary/internal/http/router/resource_test.go renamed to booklibrary/internal/webapi/resource_test.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package router_test
1+
package webapi_test
22

33
import (
44
"bytes"
@@ -12,8 +12,8 @@ import (
1212
"time"
1313

1414
"github.com/google/go-cmp/cmp"
15-
"github.com/joergjo/go-samples/booklibrary/internal/http/router"
1615
"github.com/joergjo/go-samples/booklibrary/internal/model"
16+
"github.com/joergjo/go-samples/booklibrary/internal/webapi"
1717
"go.mongodb.org/mongo-driver/bson/primitive"
1818
)
1919

@@ -102,7 +102,7 @@ func TestListBooks(t *testing.T) {
102102
}
103103
return bb, nil
104104
}
105-
router := router.NewResource(&crud)
105+
router := webapi.NewResource(&crud)
106106
path := "/"
107107
if tc.limit != -1 {
108108
path = fmt.Sprintf("%s?limit=%d", path, tc.limit)
@@ -159,7 +159,7 @@ func TestGetBook(t *testing.T) {
159159
return b, nil
160160
}
161161

162-
router := router.NewResource(&crud)
162+
router := webapi.NewResource(&crud)
163163
r := httptest.NewRequest(http.MethodGet, "/"+tc.in, nil)
164164
w := httptest.NewRecorder()
165165
router.ServeHTTP(w, r)
@@ -214,7 +214,7 @@ func TestDeleteBook(t *testing.T) {
214214
return b, nil
215215
}
216216

217-
router := router.NewResource(&crud)
217+
router := webapi.NewResource(&crud)
218218
r := httptest.NewRequest(http.MethodDelete, "/"+tc.in, nil)
219219
w := httptest.NewRecorder()
220220
router.ServeHTTP(w, r)
@@ -233,7 +233,7 @@ func TestAddBook(t *testing.T) {
233233
return book, nil
234234
}
235235

236-
router := router.NewResource(&crud)
236+
router := webapi.NewResource(&crud)
237237
book := model.Book{
238238
Author: "Jörg Jooss",
239239
Title: "Go Testing in Action",
@@ -311,7 +311,7 @@ func TestUpdateBook(t *testing.T) {
311311
t.Fatalf("Error marshaling Book: %v.", err)
312312
}
313313

314-
router := router.NewResource(&crud)
314+
router := webapi.NewResource(&crud)
315315
r := httptest.NewRequest(http.MethodPut, "/"+book.ID, bytes.NewBuffer(body))
316316
r.Header.Set("Content-Type", applicationJSON)
317317
w := httptest.NewRecorder()

booklibrary/internal/http/server/server.go renamed to booklibrary/internal/webapi/server.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package server
1+
package webapi
22

33
import (
44
"context"
@@ -12,16 +12,18 @@ import (
1212
"log/slog"
1313

1414
"github.com/joergjo/go-samples/booklibrary/internal/log"
15+
"github.com/joergjo/go-samples/booklibrary/internal/model"
1516
)
1617

17-
// New creates a new HTTP server with the given handler and port.
18-
func New(h http.Handler, port int) *http.Server {
18+
// NewServer creates a new HTTP server with the given handler and port.
19+
func NewServer(crud model.CrudService, port int) *http.Server {
20+
mux := NewMux(crud)
1921
s := http.Server{
2022
Addr: fmt.Sprintf(":%d", port),
2123
ReadTimeout: 5 * time.Second,
2224
WriteTimeout: 10 * time.Second,
2325
IdleTimeout: 120 * time.Second,
24-
Handler: h,
26+
Handler: mux,
2527
}
2628
return &s
2729
}

0 commit comments

Comments
 (0)