-
Notifications
You must be signed in to change notification settings - Fork 1
/
routing.go
148 lines (129 loc) · 3.33 KB
/
routing.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
/*
Package gorestframework implements a simple library for creating REST endpoints in an easy way.
An example could be the following:
import (
"github.com/dennybiasiolli/gorestframework"
"github.com/gorilla/mux"
"github.com/jinzhu/gorm"
)
// create the model definition
// more info here: https://gorm.io/docs/models.html
type Product struct {
gorm.Model
Code string
Price uint
}
// create migration function
func MigrateModels(db *gorm.DB) {
db.AutoMigrate(
// passing all desired models here
&Product{},
)
}
// create SetView function
func SetViews(router *mux.Router) {
gorestframework.View(&gorestframework.ViewInput{
Router: router,
PathPrefix: "/products",
ModelPtr: &Product{},
})
}
func main() {
// initializing database connection
gorestframework.InitDbConn(
"sqlite3", // DatabaseDialect,
"test.db", // DatabaseConnectionString,
MigrateModels,
)
defer gorestframework.CloseDbConn()
// start HTTP listener
gorestframework.StartHTTPListener(
true, // RouterActivateLog,
true, // RouterUseCORS,
views.SetViews,
)
}
*/
package gorestframework
import (
"context"
"flag"
"fmt"
"log"
"net/http"
"os"
"os/signal"
"time"
"github.com/gorilla/mux"
)
// StartHTTPListener starts the HTTP Listener.
// HOST and PORT can be passed via ENV, unless the default are
// - HOST=localhost
// - PORT=8000
//
// activateLog it's used to log requests to console
// useCORS enable CORS capability for all hosts, PR are welcome!
// fnSetViews is a callback function for configuring the mux.Router
func StartHTTPListener(
activateLog bool,
useCORS bool,
fnSetViews func(*mux.Router),
) {
var wait time.Duration
flag.DurationVar(
&wait,
"graceful-timeout",
time.Second*15,
"the duration for which the server gracefully wait for existing connections to finish - e.g. 15s or 1m",
)
flag.Parse()
router := mux.NewRouter()
if activateLog {
router.Use(LoggingMiddleware)
}
if useCORS {
router.Methods(http.MethodOptions)
router.Use(CORSMiddleware)
}
fnSetViews(router)
host := os.Getenv("HOST")
if host == "" {
host = "localhost"
}
port := os.Getenv("PORT")
if port == "" {
port = "8000"
}
srv := &http.Server{
Addr: fmt.Sprintf("%s:%s", host, port),
// Good practice to set timeouts to avoid Slowloris attacks.
WriteTimeout: time.Second * 15,
ReadTimeout: time.Second * 15,
IdleTimeout: time.Second * 60,
Handler: router, // Pass our instance of gorilla/mux in.
}
// run our server in a goroutine so that it doesn't block.
go func() {
log.Println("Starting http.Server on", srv.Addr)
if err := srv.ListenAndServe(); err != nil {
log.Println(err)
}
}()
c := make(chan os.Signal, 1)
// We'll accept graceful shutdowns when quit via SIGINT (Ctrl+C)
// SIGKILL, SIGQUIT or SIGTERM (Ctrl+/) will not be caught.
signal.Notify(c, os.Interrupt)
// Block until we receive our signal.
<-c
// Create a deadline to wait for.
ctx, cancel := context.WithTimeout(context.Background(), wait)
defer cancel()
// Doesn't block if no connections, but will otherwise wait
// until the timeout deadline.
srv.Shutdown(ctx)
// Optionally, you could run srv.Shutdown in a goroutine and block on
// <-ctx.Done() if your application should wait for other services
// to finalize based on context cancellation.
log.Println("Shutting down")
// os.Exit(0)
}