From 7103019890960e793deefb64987a09b33be60b42 Mon Sep 17 00:00:00 2001 From: Michael Hunteman Date: Fri, 17 May 2024 15:20:30 -0700 Subject: Add golang server --- server/cmd/main.go | 109 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 server/cmd/main.go (limited to 'server/cmd') 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)) +} -- cgit v1.2.3