Skip to content

Instantly share code, notes, and snippets.

@tsenart
Last active February 25, 2026 11:21
Show Gist options
  • Select an option

  • Save tsenart/5fc18c659814c078378d to your computer and use it in GitHub Desktop.

Select an option

Save tsenart/5fc18c659814c078378d to your computer and use it in GitHub Desktop.
HTTP Closures
package main
import (
"net/http"
"database/sql"
"fmt"
"log"
"os"
)
func helloHandler(db *sql.DB) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
var name string
// Execute the query.
row := db.QueryRow("SELECT myname FROM mytable")
if err := row.Scan(&name); err != nil {
http.Error(w, err.Error(), 500)
return
}
// Write it back to the client.
fmt.Fprintf(w, "hi %s!\n", name)
})
}
func withMetrics(l *log.Logger, next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
began := time.Now()
next.ServeHTTP(w, r)
l.Printf("%s %s took %s", r.Method, r.URL, time.Since(began))
})
}
func main() {
// Open our database connection.
db, err := sql.Open("postgres", "…")
if err != nil {
log.Fatal(err)
}
// Create our logger
logger := log.New(os.Stdout, "", 0)
// Register our handler.
http.Handle("/hello", helloHandler(db))
// Register our handler with metrics logging
http.Handle("/hello_again", withMetrics(logger, helloHandler(db)))
http.ListenAndServe(":8080", nil)
}
@Carlislegroup

Copy link
Copy Markdown

Diving into best practices to separate DB from code for scalability/flexibility, and came here from ben johnson's post (https://medium.com/@benbjohnson/structuring-applications-in-go-3b04be4ff091). Thank you for putting this together. Is there any blog posts on how to write tests against this approach? Thanks!

@ace3

ace3 commented Jul 1, 2018

Copy link
Copy Markdown

+1 very helpful

@blinderjay

Copy link
Copy Markdown

smarter way to organize golang code

@0x1F346

0x1F346 commented Oct 14, 2020

Copy link
Copy Markdown

and how do you write a test against the handler hellohandler using this approach?

Execute helloHandler and put the returned HandlerFunc into a var

@zhouzilong2020

zhouzilong2020 commented Mar 10, 2022

Copy link
Copy Markdown

and how do you write a test against the handler hellohandler using this approach?

Execute helloHandler and put the returned HandlerFunc into a var

I guess writing unit test this way is again unrealistic, just imagine if there are thousands of handlers to be tested.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment