mirror of
https://github.com/rjNemo/go-microservices-tuto
synced 2026-06-12 13:26:45 +00:00
handle post request
This commit is contained in:
parent
7d6ca2d8eb
commit
b0bc69c63d
4 changed files with 83 additions and 26 deletions
|
|
@ -17,7 +17,31 @@ type Products struct {
|
||||||
func NewProducts(logger *log.Logger) *Products { return &Products{logger: logger} }
|
func NewProducts(logger *log.Logger) *Products { return &Products{logger: logger} }
|
||||||
|
|
||||||
func (p *Products) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
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()
|
productList := data.AllProducts()
|
||||||
|
// serialize list to JSON
|
||||||
err := productList.ToJSON(w)
|
err := productList.ToJSON(w)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errMsg := fmt.Sprintf("Unable to encode request: %s\n", err)
|
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
|
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)
|
||||||
|
}
|
||||||
|
|
|
||||||
25
products/data/mockProductList.go
Normal file
25
products/data/mockProductList.go
Normal 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(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
@ -3,7 +3,6 @@ package data
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"io"
|
"io"
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Product defines the structure of a product
|
// Product defines the structure of a product
|
||||||
|
|
@ -18,38 +17,32 @@ type Product struct {
|
||||||
DeletedOn string `json:"-"`
|
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.
|
// Products is the collection of products.
|
||||||
// It encapsulates data access logic
|
// It encapsulates data access logic
|
||||||
type Products []*Product
|
type Products []*Product
|
||||||
|
|
||||||
// All returns all existing products
|
// AllProducts returns all existing products
|
||||||
func AllProducts() Products {
|
func AllProducts() Products {
|
||||||
return productList
|
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
|
// ToJSON returns all existing product in JSON format
|
||||||
func (p *Products) ToJSON(w io.Writer) error {
|
func (p *Products) ToJSON(w io.Writer) error {
|
||||||
return json.NewEncoder(w).Encode(p) // more efficient in memory and time than Marshal
|
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(),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,8 @@ func New(mux *http.ServeMux, port string) *http.Server {
|
||||||
return &http.Server{
|
return &http.Server{
|
||||||
Addr: port,
|
Addr: port,
|
||||||
Handler: mux,
|
Handler: mux,
|
||||||
|
ReadTimeout: 5 * time.Second,
|
||||||
|
WriteTimeout: 10 * time.Second,
|
||||||
IdleTimeout: 120 * time.Second, // keep connection opened to prevent Ddos attacks
|
IdleTimeout: 120 * time.Second, // keep connection opened to prevent Ddos attacks
|
||||||
ReadTimeout: 1 * time.Second,
|
|
||||||
WriteTimeout: 1 * time.Second,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue