From 53a5b271eae38913307793fa9884856709c4f822 Mon Sep 17 00:00:00 2001 From: xengineering Date: Thu, 13 Aug 2026 20:53:24 +0200 Subject: Add JSON-based API under `/api` This commit provides an unstable JSON API for communication with an upcoming Dart frontend. Later it might be part of the public interface for integration into other services. For this step it has to be ensured the semantics are not changing a lot in the future which is currently out of scope. --- view/json.go | 107 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 view/json.go (limited to 'view/json.go') diff --git a/view/json.go b/view/json.go new file mode 100644 index 0000000..deaece2 --- /dev/null +++ b/view/json.go @@ -0,0 +1,107 @@ +package view + +import ( + "encoding/json" + "io" + "net/http" + "strconv" + + "xengineering.eu/ceres/model" +) + +func CreateJSON[O model.Object](db *model.DB, constructor func() model.Object) http.Handler { + return http.HandlerFunc( + func(w http.ResponseWriter, r *http.Request) { + buf, err := io.ReadAll(r.Body) + if err != nil { + http.Error(w, "Request body could not be read: "+err.Error(), http.StatusBadRequest) + return + } + + object := constructor() + err = json.Unmarshal(buf, &object) + if err != nil { + http.Error(w, "JSON could not be parsed: "+err.Error(), http.StatusBadRequest) + return + } + + err = db.Transaction(object.Create) + if err != nil { + http.Error(w, "Object could not be saved to database: "+err.Error(), http.StatusBadRequest) + return + } + }, + ) +} + +func ReadJSON[O model.Object](db *model.DB, constructor func() model.Object) http.Handler { + return http.HandlerFunc( + func(w http.ResponseWriter, r *http.Request) { + object := constructor() + + id, err := strconv.Atoi(r.PathValue("id")) + if err == nil { + object.SetID(id) + } + + err = db.Transaction(object.Read) + if err != nil { + http.Error(w, "Object could not be read from database: "+err.Error(), http.StatusBadRequest) + return + } + + w.Header().Set("Content-Type", "application/json") + err = json.NewEncoder(w).Encode(object) + if err != nil { + http.Error(w, "Object could not be encoded to JSON: "+err.Error(), http.StatusBadRequest) + return + } + }, + ) +} + +func UpdateJSON[O model.Object](db *model.DB, constructor func() model.Object) http.Handler { + return http.HandlerFunc( + func(w http.ResponseWriter, r *http.Request) { + buf, err := io.ReadAll(r.Body) + if err != nil { + http.Error(w, "Request body could not be read: "+err.Error(), http.StatusBadRequest) + return + } + + object := constructor() + err = json.Unmarshal(buf, &object) + if err != nil { + http.Error(w, "JSON could not be parsed: "+err.Error(), http.StatusBadRequest) + return + } + + err = db.Transaction(object.Update) + if err != nil { + http.Error(w, "Object could not be updated in database: "+err.Error(), http.StatusBadRequest) + return + } + }, + ) +} + +func DeleteJSON[O model.Object](db *model.DB, constructor func() model.Object) http.Handler { + return http.HandlerFunc( + func(w http.ResponseWriter, r *http.Request) { + object := constructor() + + id, err := strconv.Atoi(r.PathValue("id")) + if err != nil { + http.Error(w, "ID of object could not be parsed to an integer: "+err.Error(), http.StatusBadRequest) + return + } + object.SetID(id) + + err = db.Transaction(object.Delete) + if err != nil { + http.Error(w, "Object could not be deleted from database: "+err.Error(), http.StatusBadRequest) + return + } + }, + ) +} -- cgit v1.3.1