Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Dependency injection via closure (handlers in multiple packages)
.
├── go.mod
├── handlers
│ ├── books
│ │ └── books.go
│ └── env.go
├── main.go
└── models
└── models.go
package books
import (
"fmt"
"log"
"net/http"
"bookstore.alexedwards.net/handlers"
"bookstore.alexedwards.net/models"
)
func Index(env *handlers.Env) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
bks, err := models.AllBooks(env.DB)
if err != nil {
log.Println(err)
http.Error(w, http.StatusText(500), 500)
return
}
for _, bk := range bks {
fmt.Fprintf(w, "%s, %s, %s, £%.2f\n", bk.Isbn, bk.Title, bk.Author, bk.Price)
}
}
}
package handlers
import (
"database/sql"
)
type Env struct {
DB *sql.DB
}
module bookstore.alexedwards.net
go 1.15
require github.com/lib/pq v1.8.0
package main
import (
"database/sql"
"log"
"net/http"
"bookstore.alexedwards.net/handlers"
"bookstore.alexedwards.net/handlers/books"
_ "github.com/lib/pq"
)
func main() {
db, err := sql.Open("postgres", "postgres://user:pass@localhost/bookstore")
if err != nil {
log.Fatal(err)
}
env := &handlers.Env{DB: db}
http.Handle("/books", books.Index(env))
http.ListenAndServe(":3000", nil)
}
package models
import (
"database/sql"
)
type Book struct {
Isbn string
Title string
Author string
Price float32
}
func AllBooks(db *sql.DB) ([]Book, error) {
rows, err := db.Query("SELECT * FROM books")
if err != nil {
return nil, err
}
defer rows.Close()
var bks []Book
for rows.Next() {
var bk Book
err := rows.Scan(&bk.Isbn, &bk.Title, &bk.Author, &bk.Price)
if err != nil {
return nil, err
}
bks = append(bks, bk)
}
if err = rows.Err(); err != nil {
return nil, err
}
return bks, nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment