diff options
author | Michael Hunteman <michael@huntm.net> | 2024-05-17 15:20:30 -0700 |
---|---|---|
committer | Michael Hunteman <michael@huntm.net> | 2024-05-17 15:20:30 -0700 |
commit | 7103019890960e793deefb64987a09b33be60b42 (patch) | |
tree | c1c9402aa250c68b2cbe13d62598232bbf20b1e2 /server/cmd | |
parent | fc5c111bcfe296bec82e1cf9fdb88fc80fb24f89 (diff) |
Add golang server
Diffstat (limited to 'server/cmd')
-rw-r--r-- | server/cmd/main.go | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/server/cmd/main.go b/server/cmd/main.go new file mode 100644 index 0000000..ed4f748 --- /dev/null +++ b/server/cmd/main.go @@ -0,0 +1,109 @@ +package main + +import ( + "encoding/json" + "log" + "net/http" + "regexp" + "strconv" + + "git.huntm.net/wedding/server/guests" +) + +type guestHandler struct { + store guestStore +} + +type guestStore interface { + Get() (map[int]guests.Guest, error) + Add(id int, guest guests.Guest) error + Update(id int, guest guests.Guest) error +} + +var ( + guestRe = regexp.MustCompile(`^/guests/*$`) + guestIdRe = regexp.MustCompile(`^/guests/([0-9]+)$`) +) + +func newGuestHandler(s guestStore) *guestHandler { + return &guestHandler{ + store: s, + } +} + +func (h *guestHandler) getGuests(w http.ResponseWriter, _ *http.Request) { + guests, err := h.store.Get() + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + } + + jsonBytes, err := json.Marshal(guests) + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + } + + w.WriteHeader(http.StatusOK) + w.Write(jsonBytes) +} + +func (h *guestHandler) createGuest(w http.ResponseWriter, r *http.Request) { + var guest guests.Guest + err := json.NewDecoder(r.Body).Decode(&guest) + defer r.Body.Close() + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + + err = h.store.Add(guest.Id, guest) + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + + w.WriteHeader(http.StatusOK) +} + +func (h *guestHandler) updateGuest(w http.ResponseWriter, r *http.Request) { + matches := guestIdRe.FindStringSubmatch(r.URL.Path) + if len(matches) < 2 { + http.Error(w, "No id found", http.StatusBadRequest) + } + + var guest guests.Guest + err := json.NewDecoder(r.Body).Decode(&guest) + defer r.Body.Close() + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + } + + id, err := strconv.Atoi(matches[1]) + if err != nil { + http.Error(w, "Cannot convert string to integer", http.StatusBadRequest) + } + + err = h.store.Update(id, guest) + if err != nil { + http.Error(w, "Guest not found", http.StatusBadRequest) + } +} + +func (h *guestHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + switch { + case r.Method == http.MethodGet && guestRe.MatchString(r.URL.Path): + h.getGuests(w, r) + case r.Method == http.MethodPost && guestRe.MatchString(r.URL.Path): + h.createGuest(w, r) + case r.Method == http.MethodPut && guestIdRe.MatchString(r.URL.Path): + h.updateGuest(w, r) + } +} + +func main() { + store := guests.NewMemStore() + guestHandler := newGuestHandler(store) + + mux := http.NewServeMux() + mux.Handle("/guests/", guestHandler) + log.Fatal(http.ListenAndServe(":8080", mux)) +} |