-
Notifications
You must be signed in to change notification settings - Fork 1
/
main.go
102 lines (85 loc) · 2.77 KB
/
main.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
package main
import (
"net/http"
"os"
"time"
"github.com/labstack/echo/v4"
toolkit "github.com/fastbill/go-service-toolkit/v4"
)
// User holds all basic user information.
type User struct {
ID uint64 `json:"id"`
Name string `json:"name" validate:"required"`
Age uint64 `json:"age" validate:"gte=18"`
}
func main() {
// Load environment variables.
toolkit.MustLoadEnvs("config")
// Set up observance (logging).
obsConfig := toolkit.ObsConfig{
AppName: os.Getenv("APP_NAME"),
LogLevel: os.Getenv("LOG_LEVEL"),
SentryURL: os.Getenv("SENTRY_URL"),
Version: os.Getenv("APP_VERSION"),
MetricsURL: os.Getenv("METRICS_URL"),
MetricsFlushInterval: 1 * time.Second,
LoggedHeaders: map[string]string{
"FastBill-RequestId": "requestId",
},
}
obs := toolkit.MustNewObs(obsConfig)
defer obs.PanicRecover()
// Set up DB connection and run migrations.
dbConfig := toolkit.DBConfig{
Dialect: os.Getenv("DB_DIALECT"),
Host: os.Getenv("DATABASE_HOST"),
Port: os.Getenv("DATABASE_PORT"),
User: os.Getenv("DATABASE_USER"),
Password: os.Getenv("DATABASE_PASSWORD"),
Name: os.Getenv("DATABASE_NAME"),
}
db := toolkit.MustSetupDB(dbConfig, obs.Logger)
defer func() {
if err := toolkit.CloseDatabase(db); err != nil {
obs.Logger.WithError(err).Error("failed to close DB connection")
}
}()
toolkit.MustEnsureDBMigrations("migrations", dbConfig)
// Set up REDIS cache.
cache := toolkit.MustNewCache(os.Getenv("REDIS_HOST"), os.Getenv("REDIS_PORT"), "testPrefix")
defer func() {
if err := cache.Close(); err != nil {
obs.Logger.WithError(err).Error("failed to close REDIS connection")
}
}()
// Set up the server.
e, connectionsClosed := toolkit.MustNewServer(obs, "")
// Set up a routes and handlers.
e.POST("/users", func(c echo.Context) error {
obs.Logger.Info("incoming request to create new user")
newUser := &User{}
err := c.Bind(newUser)
if err != nil {
obs.Logger.WithError(err).Warn("invalid request")
return c.JSON(http.StatusBadRequest, map[string]string{"msg": err.Error()})
}
if err = db.Save(newUser).Error; err != nil {
obs.Logger.WithError(err).Error("failed to save user to DB")
return c.JSON(http.StatusInternalServerError, map[string]string{"msg": err.Error()})
}
// Nonsense cache usage example
err = cache.SetJSON("latestNewUser", newUser, 0)
if err != nil {
return c.JSON(http.StatusInternalServerError, map[string]string{"msg": err.Error()})
}
return c.NoContent(http.StatusCreated)
})
// Start the server.
port := os.Getenv("PORT")
obs.Logger.WithField("port", port).Info("server running")
err := e.Start(":" + port)
if err != nil {
obs.Logger.Warn(err)
}
<-connectionsClosed // Wait for the graceful shutdown to finish.
}