2021. 4. 2
Barney
func query() (email string) {
db, err := sql.Open("postgres", "user=postgres dbname=test ...")
if err != nil {
panic(err)
}
err = db.QueryRow(`SELECT email FROM "user" WHERE id = $1`, 1).Scan(&email)
if err != nil {
panic(err)
}
return email
}
func query(db *sql.DB) (email string) {
err = db.QueryRow(`SELECT email FROM "user" WHERE id = $1`, 1).Scan(&email)
if err != nil {
panic(err)
}
return email
}
func TestQuery(t *testing.T) {
db := mockDB()
defer db.Close()
email := query(db)
assert.Equal(t, email, "email@example.com")
}
Everything in main()
func main() {
// Create logger
logger := log.New(os.Stdout, "[daangn] ", 0)
// Create handlers
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
logger.Println("Handler called")
io.WriteString(w, "Hello, world!\n")
})
// Register handlers
http.Handle("/", handler)
// Start server
http.ListenAndServe(":8080", nil)
}
Functions and Manual Wiring
type Logger interface{
Println(v ...interface{})
}
func NewLogger() Logger {
return log.New(os.Stdout, "[daangn] ", 0)
}
func main() {
logger := NewLogger()
handler := NewHandler(logger)
RegisterHandlers(handler)
StartServer()
}
Libraries and Manual Wiring
package logger
type Logger interface{
Println(v ...interface{})
}
func NewLogger() Logger {
return log.New(os.Stdout, "[daangn] ", 0)
}
func main() {
logger := logger.NewLogger()
handler := handlers.NewHandler(logger)
server.RegisterHandlers(handler)
server.StartServer()
}
func main() {
...
if err != nil {
...
}
...
if err != nil {
...
}
...
if err != nil {
...
}
...
}
Using Fx
package logger
var Module = fx.Options(
fx.Provide(NewLogger),
)
...
func main() {
app := fx.New(
server.Module,
logger.Module,
fx.Provide(
handlers.NewHandler,
),
)
app.Run()
}
A modular application built around dependency injection
We need some invocations to kick-start our application
A Hook is a pair of start and stop callbacks
Fx imposes a time limit on OnStart and OnStop hooks