package main import ( "encoding/json" "net/http" "strconv" messages "git.tornberg.me/go-cart-actor/proto" ) type PoolServer struct { pod_name string pool GrainPool } func NewPoolServer(pool GrainPool, pod_name string) *PoolServer { return &PoolServer{ pod_name: pod_name, pool: pool, } } func (s *PoolServer) HandleGet(w http.ResponseWriter, r *http.Request) error { id := r.PathValue("id") data, err := s.pool.Get(ToCartId(id)) if err != nil { return err } return s.WriteResult(w, data) } func (s *PoolServer) HandleAddSku(w http.ResponseWriter, r *http.Request) error { id := r.PathValue("id") sku := r.PathValue("sku") data, err := s.pool.Process(ToCartId(id), Message{ Type: AddRequestType, Content: &messages.AddRequest{Sku: sku, Quantity: 1}, }) if err != nil { return err } return s.WriteResult(w, data) } func ErrorHandler(fn func(w http.ResponseWriter, r *http.Request) error) func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) { err := fn(w, r) if err != nil { w.WriteHeader(http.StatusInternalServerError) w.Write([]byte(err.Error())) } } } func (s *PoolServer) WriteResult(w http.ResponseWriter, data []byte) error { w.Header().Set("Content-Type", "application/json") w.Header().Set("X-Pod-Name", s.pod_name) w.WriteHeader(http.StatusOK) _, err := w.Write(data) return err } func (s *PoolServer) HandleDeleteItem(w http.ResponseWriter, r *http.Request) error { id := r.PathValue("id") itemIdString := r.PathValue("itemId") itemId, err := strconv.Atoi(itemIdString) if err != nil { return err } data, err := s.pool.Process(ToCartId(id), Message{ Type: RemoveItemType, Content: &messages.RemoveItem{Id: int64(itemId)}, }) if err != nil { return err } return s.WriteResult(w, data) } type SetDelivery struct { Provider string `json:"provider"` Items []int64 `json:"items"` } func (s *PoolServer) HandleSetDelivery(w http.ResponseWriter, r *http.Request) error { id := r.PathValue("id") delivery := SetDelivery{} err := json.NewDecoder(r.Body).Decode(&delivery) if err != nil { return err } data, err := s.pool.Process(ToCartId(id), Message{ Type: SetDeliveryType, Content: &messages.SetDelivery{ Provider: delivery.Provider, Items: delivery.Items, }, }) if err != nil { return err } return s.WriteResult(w, data) } func (s *PoolServer) Serve() *http.ServeMux { mux := http.NewServeMux() mux.HandleFunc("GET /{id}", ErrorHandler(s.HandleGet)) mux.HandleFunc("GET /{id}/add/{sku}", ErrorHandler(s.HandleAddSku)) mux.HandleFunc("DELETE /{id}/{itemId}", ErrorHandler(s.HandleDeleteItem)) mux.HandleFunc("POST /{id}/delivery", ErrorHandler(s.HandleSetDelivery)) return mux }