Skip to content

Instantly share code, notes, and snippets.

@tsenart
Last active March 24, 2024 08:59
Show Gist options
  • Save tsenart/5fc18c659814c078378d to your computer and use it in GitHub Desktop.
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

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
Copy link

ace3 commented Jul 1, 2018

+1 very helpful

@blinderjay
Copy link

smarter way to organize golang code

@Gimongi
Copy link

Gimongi commented Oct 14, 2020

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
Copy link

zhouzilong2020 commented Mar 10, 2022

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