App Handler with app config

I tried to make AppHandler {Config: AppConfig, Handler: func()}
But it did not come up well. It is working but looking very ugly.

Previously I was using like this

t := templates.LoadTemplates() //This function loads all html file using parseglob…
I used a middleware and attached this “t” in the context.

I have to do the same for Databse.
I have to do the same for Localizer and everything

So, now I am thinking to have all in the config struct

type Config struct {
T *template.Template
DB *sql.DB
}

again now, for every route, I have to pass this config.
Instead of this, I would like to have one main route which will have this config file.
This main route will handle all the routes. How do I implement this in go’s way?

Can an interface have config details?
So I can create a contract and access the config?

Please share some of your code or idea to implement this.

As many people said, if I use go, I have to use it by myself. There is no support. Django has very good support. I am really confused… Statically typed, high performance makes me to stick with this language

No matter what language you choose, you’ll have to build your application yourself (or with your team). I have found the community (here, on Reddit, and in the Discord!) to be pretty supportive. That said, I’m not exactly sure what you are trying to accomplish and what your problem is. It sounds like you’re trying to pass config to your routes and you’re unsure about where/how to store your DB connection pool?

DB Object

I think this is one of the areas where global variables are OK. For example, having a global SQL connection pool object called DB is a pattern I’ve seen plenty. Often I find it useful to extract my data access layer to its’ own package. This allows me to re-export it in multiple executables as needed. For example: I have a project where I have a scheduler service that runs and uses the same queries/data access layer as my main web executable to do things like send scheduled emails and build resource-intensive reports nightly.

Here’s a fictional queries package to demonstrate this:

// Package queries provides data access layer for app.
package queries

import (
	"database/sql"

	_ "github.com/go-sql-driver/mysql"
)

// Global connection pool object
var db *sql.DB

// InitDatabase sets the global connection pool object to allow 
// execution of SQL queries. Call `ShutdownDB` to close.
func InitDB(connString string) error {
	conn, err := sql.Open("mysql", connString)
	if err != nil {
		return err
	}
	// Set our global db oject
	db = conn
	return nil
}

// ShutdownDB calls `Close()` on global connection pool object.
func ShutdownDB() error {
	return db.Close()
}

Then in your main package where you are initializing your routes, etc. be sure to also initialized queries and shut down:

package main

import (
	"github.com/my-package/queries"
)

func main() {
	// Initialize connection pool in queries. In the real world, handle errors
	err := queries.InitDB("user:password@/dbname")
	// Close our DB connection pool on exit
	defer queries.ShutdownDB()
}

As I mentioned above, the nice thing about this is: any package in the future can re-use your data access layer / queries. I find uses for this all the time. I create golang executables to do scripting tasks for example. I create executables to synchronize data with external APIs when it gets out of sync. Etc. Your use case might not be the same as mine, but, I find a lot of value in having my data layer in an reusable package. It’s also handy to have one place to search for SQL queries.

Templates / Request Context

In the case of your template question, I wonder if you just need a wrapper around your handler funcs that includes the template and whatever else is specific to that route? Let’s create a function signature that contains the extra data we want:

// Configuration for our route. Expect one for each route/template.
type RouteConfig struct {
	Template *template.Template
}

// TemplateHandle is like http.HandlerFunc, but has a third parameter for config.
type TemplateHandle func(http.ResponseWriter, *http.Request, RouteConfig)

… then let’s create a wrapper to turn these into http.HandlerFunc:

// newHandler wraps our TemplateHandle func
func newTemplateHandler(h TemplateHandle, c RouteConfig) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		h(w, r, c)
	}
}

… and then let’s use our new TemplateHandle wrapper:

// Handler for our home page
func Home(w http.ResponseWriter, r *http.Request, c RouteConfig) {
	c.Template.Execute(w, nil)
}

// Handler for our user detail page
func User(w http.ResponseWriter, r *http.Request, c RouteConfig) {
	c.Template.Execute(w, nil)
}

func main() {
	t := template.Must(template.New("home").Parse("<h1>Hello Home!</h1>"))
	// Config for home route
	homeConfig := RouteConfig{t}
	// Wrapped handler for home route
	http.HandleFunc("/", newTemplateHandler(Home, homeConfig))

	// Config for our /user/ route.
	userTemplate := template.Must(template.New("user").Parse("<h1>User Detail</h1>"))
	// Config for home route
	userConfig := RouteConfig{userTemplate}
	http.HandleFunc("/user", newTemplateHandler(User, userConfig))
	log.Fatal(http.ListenAndServe(":8088", nil))
}

There are other approaches but this should get you started. As an alterative take a look at this:

And you could just create a http.Handler for your routes as well:

In your case your handler struct would have the template baked in and satisfy ServeHTTP. Anyway, there are quite a few options. I think what you’re confused about is: go is opinionated about how you write/format your code but not opinionated about how you structure your project. If you want to use a more opinionated framework, there are options. Maybe check this reddit thread for ideas?

Hello there. I would suggest to try and add a wrapper around http.Server and use methods as handlers. Something like this:

type Server struct {
    srv http.Server
    cfg Config // Your config
}

func (s *Server) Handler(w http.ResponseWriter, r *http.Request) {
    // Do something with direct access to your config with s.cfg...
}

I’ve only been talking to golang for a couple of months… Here is the result… example It will probably help…

You have written the db connection on every file. I don’t think that is a good idea.

Please see my question. Implement the db on the separate package and import it on the main page.
Finally you need to pass that every handler. That is the challenge.