summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxengineering <me@xengineering.eu>2024-10-23 20:34:57 +0200
committerxengineering <me@xengineering.eu>2024-10-23 20:34:57 +0200
commite66691083a2455c29b50a2970c0aba1d6afca753 (patch)
tree1f3192351038693b5fc219148fbc39cf2e869a87
parent9d14fee31507551149dcdf31c59798624330f3f3 (diff)
downloadceres-e66691083a2455c29b50a2970c0aba1d6afca753.tar
ceres-e66691083a2455c29b50a2970c0aba1d6afca753.tar.zst
ceres-e66691083a2455c29b50a2970c0aba1d6afca753.zip
Switch to http.Handler
The used `func(http.ResponseWriter, *http.Request)` return values made the HTTP handler factory functions quite unreadable. Thus it is switched to the http.Handler type.
-rw-r--r--controller/recipe.go150
-rw-r--r--server.go23
-rw-r--r--view/favicon.go8
-rw-r--r--view/index.go8
-rw-r--r--view/index_test.go2
-rw-r--r--view/recipe.go102
-rw-r--r--view/recipes.go32
-rw-r--r--view/version.go18
8 files changed, 185 insertions, 158 deletions
diff --git a/controller/recipe.go b/controller/recipe.go
index 33d4063..5e5fc3d 100644
--- a/controller/recipe.go
+++ b/controller/recipe.go
@@ -10,80 +10,86 @@ import (
"xengineering.eu/ceres/model"
)
-func RecipeCreate(db *model.DB) func(http.ResponseWriter, *http.Request) {
- return func(w http.ResponseWriter, r *http.Request) {
- buf, err := io.ReadAll(r.Body)
- if err != nil {
- http.Error(w, err.Error(), http.StatusInternalServerError)
- return
- }
-
- recipe := model.Recipe{}
- err = json.Unmarshal(buf, &recipe)
- if err != nil {
- http.Error(w, err.Error(), http.StatusBadRequest)
- return
- }
-
- recipe.LastChanged = fmt.Sprint(time.Now().Unix())
- recipe.Created = recipe.LastChanged
-
- var obj model.Object = &recipe
- err = db.Transaction(obj.Create)
- if err != nil {
- http.Error(w, err.Error(), http.StatusInternalServerError)
- return
- }
-
- http.Redirect(w, r, "/recipe/"+recipe.Id, http.StatusSeeOther)
- }
+func RecipeCreate(db *model.DB) http.Handler {
+ return http.HandlerFunc(
+ func(w http.ResponseWriter, r *http.Request) {
+ buf, err := io.ReadAll(r.Body)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+
+ recipe := model.Recipe{}
+ err = json.Unmarshal(buf, &recipe)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusBadRequest)
+ return
+ }
+
+ recipe.LastChanged = fmt.Sprint(time.Now().Unix())
+ recipe.Created = recipe.LastChanged
+
+ var obj model.Object = &recipe
+ err = db.Transaction(obj.Create)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+
+ http.Redirect(w, r, "/recipe/"+recipe.Id, http.StatusSeeOther)
+ },
+ )
}
-func RecipeUpdate(db *model.DB) func(http.ResponseWriter, *http.Request) {
- return func(w http.ResponseWriter, r *http.Request) {
- buf, err := io.ReadAll(r.Body)
- if err != nil {
- http.Error(w, err.Error(), http.StatusInternalServerError)
- return
- }
-
- recipe := model.Recipe{}
- err = json.Unmarshal(buf, &recipe)
- if err != nil {
- http.Error(w, err.Error(), http.StatusBadRequest)
- return
- }
-
- if recipe.Id != r.PathValue("id") {
- http.Error(w, "IDs in URL and JSON do not match", http.StatusBadRequest)
- return
- }
-
- recipe.LastChanged = fmt.Sprint(time.Now().Unix())
-
- var obj model.Object = &recipe
- err = db.Transaction(obj.Update)
- if err != nil {
- http.Error(w, err.Error(), http.StatusInternalServerError)
- return
- }
-
- http.Redirect(w, r, "/recipe/"+recipe.Id, http.StatusSeeOther)
- }
+func RecipeUpdate(db *model.DB) http.Handler {
+ return http.HandlerFunc(
+ func(w http.ResponseWriter, r *http.Request) {
+ buf, err := io.ReadAll(r.Body)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+
+ recipe := model.Recipe{}
+ err = json.Unmarshal(buf, &recipe)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusBadRequest)
+ return
+ }
+
+ if recipe.Id != r.PathValue("id") {
+ http.Error(w, "IDs in URL and JSON do not match", http.StatusBadRequest)
+ return
+ }
+
+ recipe.LastChanged = fmt.Sprint(time.Now().Unix())
+
+ var obj model.Object = &recipe
+ err = db.Transaction(obj.Update)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+
+ http.Redirect(w, r, "/recipe/"+recipe.Id, http.StatusSeeOther)
+ },
+ )
}
-func RecipeDelete(db *model.DB) func(http.ResponseWriter, *http.Request) {
- return func(w http.ResponseWriter, r *http.Request) {
- recipe := model.Recipe{}
- recipe.Id = r.PathValue("id")
-
- var obj model.Object = &recipe
- err := db.Transaction(obj.Delete)
- if err != nil {
- http.Error(w, err.Error(), http.StatusInternalServerError)
- return
- }
-
- http.Redirect(w, r, "/recipes", http.StatusSeeOther)
- }
+func RecipeDelete(db *model.DB) http.Handler {
+ return http.HandlerFunc(
+ func(w http.ResponseWriter, r *http.Request) {
+ recipe := model.Recipe{}
+ recipe.Id = r.PathValue("id")
+
+ var obj model.Object = &recipe
+ err := db.Transaction(obj.Delete)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+
+ http.Redirect(w, r, "/recipes", http.StatusSeeOther)
+ },
+ )
}
diff --git a/server.go b/server.go
index 35cd44d..3b17227 100644
--- a/server.go
+++ b/server.go
@@ -19,21 +19,24 @@ var static embed.FS
func NewServer(addr string, db *model.DB) *Server {
mux := http.NewServeMux()
- mux.Handle("GET /static/", http.StripPrefix("/static/", http.FileServer(http.FS(static))))
+ mux.Handle(
+ "GET /static/",
+ http.StripPrefix("/static/", http.FileServer(http.FS(static))),
+ )
- mux.HandleFunc("GET /version", view.VersionRead(version))
+ mux.Handle("GET /version", view.VersionRead(version))
- mux.HandleFunc("GET /recipes", view.RecipesRead(db))
+ mux.Handle("GET /recipes", view.RecipesRead(db))
- mux.HandleFunc("GET /recipe/create", view.RecipeCreate)
- mux.HandleFunc("POST /recipe", controller.RecipeCreate(db))
- mux.HandleFunc("GET /recipe/{id}", view.RecipeRead(db))
- mux.HandleFunc("POST /recipe/{id}", controller.RecipeUpdate(db))
- mux.HandleFunc("DELETE /recipe/{id}", controller.RecipeDelete(db))
+ mux.Handle("GET /recipe/create", view.RecipeCreate())
+ mux.Handle("POST /recipe", controller.RecipeCreate(db))
+ mux.Handle("GET /recipe/{id}", view.RecipeRead(db))
+ mux.Handle("POST /recipe/{id}", controller.RecipeUpdate(db))
+ mux.Handle("DELETE /recipe/{id}", controller.RecipeDelete(db))
- mux.HandleFunc("GET /favicon.ico", view.FaviconRead)
+ mux.Handle("GET /favicon.ico", view.FaviconRead())
- mux.HandleFunc("GET /", view.IndexRead)
+ mux.Handle("GET /", view.IndexRead())
var srv http.Server
srv.Addr = addr
diff --git a/view/favicon.go b/view/favicon.go
index 8e3ea79..67d7051 100644
--- a/view/favicon.go
+++ b/view/favicon.go
@@ -4,6 +4,10 @@ import (
"net/http"
)
-func FaviconRead(w http.ResponseWriter, r *http.Request) {
- w.WriteHeader(http.StatusNoContent)
+func FaviconRead() http.Handler {
+ return http.HandlerFunc(
+ func(w http.ResponseWriter, r *http.Request) {
+ w.WriteHeader(http.StatusNoContent)
+ },
+ )
}
diff --git a/view/index.go b/view/index.go
index 7d12783..46389d5 100644
--- a/view/index.go
+++ b/view/index.go
@@ -4,6 +4,10 @@ import (
"net/http"
)
-func IndexRead(w http.ResponseWriter, r *http.Request) {
- http.Redirect(w, r, "/recipes", http.StatusSeeOther)
+func IndexRead() http.Handler {
+ return http.HandlerFunc(
+ func(w http.ResponseWriter, r *http.Request) {
+ http.Redirect(w, r, "/recipes", http.StatusSeeOther)
+ },
+ )
}
diff --git a/view/index_test.go b/view/index_test.go
index 3ab35d5..68167f6 100644
--- a/view/index_test.go
+++ b/view/index_test.go
@@ -14,7 +14,7 @@ func TestIndexRead(t *testing.T) {
rec := httptest.NewRecorder()
- handler := http.HandlerFunc(IndexRead)
+ handler := IndexRead()
handler.ServeHTTP(rec, req)
if rec.Code != http.StatusSeeOther {
diff --git a/view/recipe.go b/view/recipe.go
index c18c078..889f6ec 100644
--- a/view/recipe.go
+++ b/view/recipe.go
@@ -6,58 +6,64 @@ import (
"xengineering.eu/ceres/model"
)
-func RecipeRead(db *model.DB) func(http.ResponseWriter, *http.Request) {
- return func(w http.ResponseWriter, r *http.Request) {
- recipe := model.Recipe{}
- recipe.Id = r.PathValue("id")
-
- var obj model.Object = &recipe
- err := db.Transaction(obj.Read)
- if err != nil {
- http.Error(w, err.Error(), http.StatusInternalServerError)
- return
- }
-
- template := "recipe"
- view, ok := r.URL.Query()["view"]
- if ok {
- if len(view) > 1 {
- http.Error(w, "More than one 'view' parameter given in URL", http.StatusBadRequest)
+func RecipeRead(db *model.DB) http.Handler {
+ return http.HandlerFunc(
+ func(w http.ResponseWriter, r *http.Request) {
+ recipe := model.Recipe{}
+ recipe.Id = r.PathValue("id")
+
+ var obj model.Object = &recipe
+ err := db.Transaction(obj.Read)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+
+ template := "recipe"
+ view, ok := r.URL.Query()["view"]
+ if ok {
+ if len(view) > 1 {
+ http.Error(w, "More than one 'view' parameter given in URL", http.StatusBadRequest)
+ return
+ }
+ template = view[0]
+ }
+
+ is_valid := false
+ valid_templates := []string{
+ "recipe",
+ "recipe-edit",
+ "recipe-confirm-deletion",
+ }
+ for _, v := range valid_templates {
+ if template == v {
+ is_valid = true
+ }
+ }
+ if !is_valid {
+ http.Error(w, "Unsupported view: "+template, http.StatusBadRequest)
return
}
- template = view[0]
- }
-
- is_valid := false
- valid_templates := []string{
- "recipe",
- "recipe-edit",
- "recipe-confirm-deletion",
- }
- for _, v := range valid_templates {
- if template == v {
- is_valid = true
+
+ err = html.ExecuteTemplate(w, template, recipe)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
}
- }
- if !is_valid {
- http.Error(w, "Unsupported view: "+template, http.StatusBadRequest)
- return
- }
-
- err = html.ExecuteTemplate(w, template, recipe)
- if err != nil {
- http.Error(w, err.Error(), http.StatusInternalServerError)
- return
- }
- }
+ },
+ )
}
-func RecipeCreate(w http.ResponseWriter, r *http.Request) {
- recipe := model.Recipe{}
+func RecipeCreate() http.Handler {
+ return http.HandlerFunc(
+ func(w http.ResponseWriter, r *http.Request) {
+ recipe := model.Recipe{}
- err := html.ExecuteTemplate(w, "recipe-edit", recipe)
- if err != nil {
- http.Error(w, err.Error(), http.StatusInternalServerError)
- return
- }
+ err := html.ExecuteTemplate(w, "recipe-edit", recipe)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+ },
+ )
}
diff --git a/view/recipes.go b/view/recipes.go
index e7153cd..8cd107e 100644
--- a/view/recipes.go
+++ b/view/recipes.go
@@ -6,21 +6,23 @@ import (
"xengineering.eu/ceres/model"
)
-func RecipesRead(db *model.DB) func(http.ResponseWriter, *http.Request) {
- return func(w http.ResponseWriter, r *http.Request) {
- recipes := make(model.Recipes, 0)
+func RecipesRead(db *model.DB) http.Handler {
+ return http.HandlerFunc(
+ func(w http.ResponseWriter, r *http.Request) {
+ recipes := make(model.Recipes, 0)
- var obj model.Object = &recipes
- err := db.Transaction(obj.Read)
- if err != nil {
- http.Error(w, err.Error(), http.StatusInternalServerError)
- return
- }
+ var obj model.Object = &recipes
+ err := db.Transaction(obj.Read)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
- err = html.ExecuteTemplate(w, "recipes", recipes)
- if err != nil {
- http.Error(w, err.Error(), http.StatusInternalServerError)
- return
- }
- }
+ err = html.ExecuteTemplate(w, "recipes", recipes)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+ },
+ )
}
diff --git a/view/version.go b/view/version.go
index faf91b1..337200e 100644
--- a/view/version.go
+++ b/view/version.go
@@ -5,13 +5,15 @@ import (
"net/http"
)
-func VersionRead(version string) func(http.ResponseWriter, *http.Request) {
- return func(w http.ResponseWriter, r *http.Request) {
- if version == "" {
- http.Error(w, "This build has no version information", http.StatusNotFound)
- return
- }
+func VersionRead(version string) http.Handler {
+ return http.HandlerFunc(
+ func(w http.ResponseWriter, r *http.Request) {
+ if version == "" {
+ http.Error(w, "This build has no version information", http.StatusNotFound)
+ return
+ }
- fmt.Fprintln(w, version)
- }
+ fmt.Fprintln(w, version)
+ },
+ )
}