From b0bc69c63dfe4b2d6f629d4c3726a788b65b038f Mon Sep 17 00:00:00 2001 From: Ruidy Nemausat Date: Tue, 14 Jul 2020 10:35:49 +0200 Subject: [PATCH] handle post request --- handlers/products.go | 39 ++++++++++++++++++++++++++++++ products/data/mockProductList.go | 25 +++++++++++++++++++ products/data/product.go | 41 +++++++++++++------------------- server/server.go | 4 ++-- 4 files changed, 83 insertions(+), 26 deletions(-) create mode 100644 products/data/mockProductList.go diff --git a/handlers/products.go b/handlers/products.go index e8e02b0..7b9e06f 100644 --- a/handlers/products.go +++ b/handlers/products.go @@ -17,7 +17,31 @@ type Products struct { func NewProducts(logger *log.Logger) *Products { return &Products{logger: logger} } func (p *Products) ServeHTTP(w http.ResponseWriter, r *http.Request) { + // get resources + if r.Method == http.MethodGet { + p.getProducts(w, r) + return + } + // create one resource + if r.Method == http.MethodPost { + p.addProduct(w, r) + return + } + // update one resource + // if r.Method == http.MethodPut { + // p.updateProduct(w,r) + // return + // } + // catch all other HTTP requests + w.WriteHeader(http.StatusMethodNotAllowed) +} + +// getProducts writes all products to response in JSON format +func (p *Products) getProducts(w http.ResponseWriter, r *http.Request) { + p.logger.Println("Handle 'GET' request") + // fetch products from the datastore productList := data.AllProducts() + // serialize list to JSON err := productList.ToJSON(w) if err != nil { errMsg := fmt.Sprintf("Unable to encode request: %s\n", err) @@ -25,3 +49,18 @@ func (p *Products) ServeHTTP(w http.ResponseWriter, r *http.Request) { return } } + +func (p *Products) addProduct(w http.ResponseWriter, r *http.Request) { + p.logger.Println("Handle 'POST' request") + // create a new product + newProd := &data.Product{} + // deserialize JSON to product + err := newProd.FromJSON(r.Body) + if err != nil { + errMsg := fmt.Sprintf("Unable to decode data: %s\n", err) + http.Error(w, errMsg, http.StatusBadRequest) + return + } + p.logger.Printf("product: %#v", newProd) + data.AddProduct(newProd) +} diff --git a/products/data/mockProductList.go b/products/data/mockProductList.go new file mode 100644 index 0000000..87471ee --- /dev/null +++ b/products/data/mockProductList.go @@ -0,0 +1,25 @@ +package data + +import "time" + +// dummy persistence layer +var productList = []*Product{ + { + ID: 1, + Name: "Latte", + Description: "Prothy Milky Coffee", + Price: 2.45, + SKU: "abc123", + CreatedOn: time.Now().String(), + UpdatedOn: time.Now().String(), + }, + { + ID: 2, + Name: "Espresso", + Description: "Short Strong Coffee without Milk", + Price: 1.99, + SKU: "efg456", + CreatedOn: time.Now().String(), + UpdatedOn: time.Now().String(), + }, +} diff --git a/products/data/product.go b/products/data/product.go index 26bae00..76e61ac 100644 --- a/products/data/product.go +++ b/products/data/product.go @@ -3,7 +3,6 @@ package data import ( "encoding/json" "io" - "time" ) // Product defines the structure of a product @@ -18,38 +17,32 @@ type Product struct { DeletedOn string `json:"-"` } +// FromJSON read JSON data to create a new product +func (p *Product) FromJSON(r io.Reader) error { + return json.NewDecoder(r).Decode(p) +} + // Products is the collection of products. // It encapsulates data access logic type Products []*Product -// All returns all existing products +// AllProducts returns all existing products func AllProducts() Products { return productList } +// AddProduct add a Product to the dataStore +func AddProduct(p *Product) { + p.ID = getNextID() + productList = append(productList, p) +} + +// getNextID handle ID creation +func getNextID() int { + return productList[len(productList)-1].ID + 1 +} + // ToJSON returns all existing product in JSON format func (p *Products) ToJSON(w io.Writer) error { return json.NewEncoder(w).Encode(p) // more efficient in memory and time than Marshal } - -// dummy persistence layer -var productList = []*Product{ - { - ID: 1, - Name: "Latte", - Description: "Prothy Milky Coffee", - Price: 2.45, - SKU: "abc123", - CreatedOn: time.Now().String(), - UpdatedOn: time.Now().String(), - }, - { - ID: 2, - Name: "Espresso", - Description: "Short Strong Coffee without Milk", - Price: 1.99, - SKU: "efg456", - CreatedOn: time.Now().String(), - UpdatedOn: time.Now().String(), - }, -} diff --git a/server/server.go b/server/server.go index eb275a2..4f88841 100644 --- a/server/server.go +++ b/server/server.go @@ -10,8 +10,8 @@ func New(mux *http.ServeMux, port string) *http.Server { return &http.Server{ Addr: port, Handler: mux, + ReadTimeout: 5 * time.Second, + WriteTimeout: 10 * time.Second, IdleTimeout: 120 * time.Second, // keep connection opened to prevent Ddos attacks - ReadTimeout: 1 * time.Second, - WriteTimeout: 1 * time.Second, } }