Skip to content

Instantly share code, notes, and snippets.

@dlisboa
Last active July 12, 2024 17:38
Show Gist options
  • Save dlisboa/5891fa405b5ce0fafb5ff4200a999c6e to your computer and use it in GitHub Desktop.
Save dlisboa/5891fa405b5ce0fafb5ff4200a999c6e to your computer and use it in GitHub Desktop.
Example Page Load/Render phase
package main
import (
"io"
"net/http"
"net/url"
)
func main() {
// ...
}
func handler(w http.ResponseWriter, r *http.Request) {
r.ParseForm()
s := NewSearchPage(r.Form)
// does it all at once, avoids N+1
err := s.Load(db)
if err != nil {
w.WriteHeader(500)
s.Err = err
s.RenderError(w)
}
w.WriteHeader(200)
s.RenderHTML(w)
}
type SearchPage struct {
page.Base
// this is used in the load phase
query string
// this will be rendered
Err error
Results []Result
}
func NewSearchPage(vals url.Values) *SearchPage {
return &SearchPage{
query: vals.Get("q"),
}
}
func (s *SearchPage) RenderHTML(w io.Writer) {}
func (s *SearchPage) RenderError(w io.Writer) {}
// db can be changed to an interface: Load(store SearchStore)
// WARNING: do not use db in a loop, it'll cause N+1
func (p *SearchPage) Load(db *dbsqlc.Queries) {
dbresults, err := db.SearchFullText(p.query)
if err != nil {
// ...
}
p.Results = ResultsFrom(dbresults)
}
// converts from db model, avoids coupling presentation and DB
func ResultsFrom(res []dbsqlc.Result) []Result {
var results []Result
for res.Next() {
var r Result
res.Scan(&r)
results = append(results, r)
}
return results
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment