handle post request

This commit is contained in:
Ruidy Nemausat 2020-07-14 10:35:49 +02:00
parent 7d6ca2d8eb
commit b0bc69c63d
4 changed files with 83 additions and 26 deletions

View file

@ -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)
}

View file

@ -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(),
},
}

View file

@ -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(),
},
}

View file

@ -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,
}
}