You've already forked golang-base-project
Improves documentation (#13)
* Documents all env variables and adds an example project * Adds godoc comments * Fixed package naming issue
This commit is contained in:
33
main.go
33
main.go
@ -15,58 +15,85 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// staticFS is an embedded file system
|
||||
//go:embed dist/*
|
||||
var staticFS embed.FS
|
||||
|
||||
// Run is the main function that runs the entire package and starts the webserver, this is called by /cmd/base/main.go
|
||||
func Run() {
|
||||
// When generating random strings we need to provide a seed otherwise we always get the same strings the next time our application starts
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
|
||||
var t *template.Template
|
||||
// We load environment variables, these are only read when the application launches
|
||||
conf := loadEnvVariables()
|
||||
|
||||
// We connect to the database using the configuration generated from the environment variables.
|
||||
db, err := connectToDatabase(conf)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
// Once a database connection is established we run any needed migrations
|
||||
err = migrateDatabase(db)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
// t will hold all our html templates used to render pages
|
||||
var t *template.Template
|
||||
|
||||
// We parse and load the html files into our t variable
|
||||
t, err = loadTemplates()
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
// A gin Engine instance with the default configuration
|
||||
r := gin.Default()
|
||||
|
||||
// We create a new cookie store with a key used to secure cookies with HMAC
|
||||
store := cookie.NewStore([]byte(conf.CookieSecret))
|
||||
|
||||
// We define our session middleware to be used globally on all routes
|
||||
r.Use(sessions.Sessions("golang_base_project_session", store))
|
||||
|
||||
// We pase our template variable t to the gin engine so it can be used to render html pages
|
||||
r.SetHTMLTemplate(t)
|
||||
|
||||
// our assets are only located in a section of our file system. so we create a sub file system.
|
||||
subFS, err := fs.Sub(staticFS, "dist/assets")
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
// All static assets are under the /assets path so we make this its own group called assets
|
||||
assets := r.Group("/assets")
|
||||
|
||||
// This middleware sets the Cache-Control header and is applied to the assets group only
|
||||
assets.Use(middleware.Cache(conf.CacheMaxAge))
|
||||
|
||||
// All requests to /assets will use the sub fil system which contains all our static assets
|
||||
assets.StaticFS("/", http.FS(subFS))
|
||||
|
||||
// Session middleware is applied to all groups after this point.
|
||||
r.Use(middleware.Session(db))
|
||||
|
||||
// A General middleware is defined to add default headers to improve site security
|
||||
r.Use(middleware.General())
|
||||
|
||||
// A new instance of the routes controller is created
|
||||
controller := routes.New(db, conf)
|
||||
|
||||
// Any request to / will call controller.Index
|
||||
r.GET("/", controller.Index)
|
||||
|
||||
// We want to handle both POST and GET requests on the /search route. We define both but use the same function to handle the requests.
|
||||
r.GET("/search", controller.Search)
|
||||
r.POST("/search", controller.Search)
|
||||
|
||||
// We define our 404 handler for when a page can not be found
|
||||
r.NoRoute(controller.NoRoute)
|
||||
|
||||
// noAuth is a group for routes which should only be accessed if the user is not authenticated
|
||||
noAuth := r.Group("/")
|
||||
noAuth.Use(middleware.NoAuth())
|
||||
|
||||
@ -77,6 +104,7 @@ func Run() {
|
||||
noAuth.GET("/user/password/forgot", controller.ForgotPassword)
|
||||
noAuth.GET("/user/password/reset/:token", controller.ResetPassword)
|
||||
|
||||
// We make a separate group for our post requests on the same endpoints so that we can define our throttling middleware on POST requests only.
|
||||
noAuthPost := noAuth.Group("/")
|
||||
noAuthPost.Use(middleware.Throttle(conf.RequestsPerMinute))
|
||||
|
||||
@ -86,6 +114,7 @@ func Run() {
|
||||
noAuthPost.POST("/user/password/forgot", controller.ForgotPasswordPost)
|
||||
noAuthPost.POST("/user/password/reset/:token", controller.ResetPasswordPost)
|
||||
|
||||
// the admin group handles routes that should only be accessible to authenticated users
|
||||
admin := r.Group("/")
|
||||
admin.Use(middleware.Auth())
|
||||
admin.Use(middleware.Sensitive())
|
||||
@ -95,6 +124,8 @@ func Run() {
|
||||
admin.POST("/admin", controller.Admin)
|
||||
admin.GET("/logout", controller.Logout)
|
||||
|
||||
// This starts our webserver, our application will not stop running or go past this point unless
|
||||
// an error occurs or the web server is stopped for some reason. It is designed to run forever.
|
||||
err = r.Run(conf.Port)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
|
Reference in New Issue
Block a user