get all products

This commit is contained in:
Ruidy Nemausat 2020-07-13 23:21:30 +02:00
commit 7d6ca2d8eb
6 changed files with 148 additions and 0 deletions

3
go.mod Normal file
View file

@ -0,0 +1,3 @@
module github.com/rjNemo/go-micro
go 1.14

1
go.sum Normal file
View file

@ -0,0 +1 @@
golang.org/x/tools v0.0.0-20200713195033-f8240f79c3d3 h1:xV8QVipADSbgfDrrjnUyOJILDkpbFpyoLV4x06POJ7I=

27
handlers/products.go Normal file
View file

@ -0,0 +1,27 @@
package handlers
import (
"fmt"
"log"
"net/http"
"github.com/rjNemo/go-micro/products/data"
)
// Products is a handler for Products API service
type Products struct {
logger *log.Logger
}
// NewProducts creates a Products handler
func NewProducts(logger *log.Logger) *Products { return &Products{logger: logger} }
func (p *Products) ServeHTTP(w http.ResponseWriter, r *http.Request) {
productList := data.AllProducts()
err := productList.ToJSON(w)
if err != nil {
errMsg := fmt.Sprintf("Unable to encode request: %s\n", err)
http.Error(w, errMsg, http.StatusInternalServerError)
return
}
}

45
main.go Normal file
View file

@ -0,0 +1,45 @@
package main
import (
"context"
"log"
"net/http"
"os"
"os/signal"
"time"
"github.com/rjNemo/go-micro/handlers"
"github.com/rjNemo/go-micro/server"
)
const port = ":5000"
func main() {
logger := log.New(os.Stdout, "Product API: ", log.LstdFlags|log.Lshortfile)
// create the handlers
productsHandler := handlers.NewProducts(logger)
// create a server mux and register the handlers
mux := http.NewServeMux()
mux.Handle("/", productsHandler)
// creates a new server
srv := server.New(mux, port)
// non blocking application server
go func() {
logger.Printf("Server started at address http://localhost%s...", port)
logger.Fatalf("Server failed: %v", srv.ListenAndServe())
}()
// catch sigterm or interrupt and gracefully terminates the server
sigChan := make(chan os.Signal)
signal.Notify(sigChan, os.Interrupt)
signal.Notify(sigChan, os.Kill)
sig := <-sigChan
logger.Printf("Received %v signal... graceful shutdown", sig)
toCtx, _ := context.WithTimeout(context.Background(), 30*time.Second)
srv.Shutdown(toCtx)
}

55
products/data/product.go Normal file
View file

@ -0,0 +1,55 @@
package data
import (
"encoding/json"
"io"
"time"
)
// Product defines the structure of a product
type Product struct {
ID int `json:"id"` //TODO: use uuid
Name string `json:"name"`
Description string `json:"description"`
Price float32 `json:"price"` // TODO: use int
SKU string `json:"sku"`
CreatedOn string `json:"-"`
UpdatedOn string `json:"-"`
DeletedOn string `json:"-"`
}
// Products is the collection of products.
// It encapsulates data access logic
type Products []*Product
// All returns all existing products
func AllProducts() Products {
return productList
}
// 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(),
},
}

17
server/server.go Normal file
View file

@ -0,0 +1,17 @@
package server
import (
"net/http"
"time"
)
// New creates a server using given mux and port
func New(mux *http.ServeMux, port string) *http.Server {
return &http.Server{
Addr: port,
Handler: mux,
IdleTimeout: 120 * time.Second, // keep connection opened to prevent Ddos attacks
ReadTimeout: 1 * time.Second,
WriteTimeout: 1 * time.Second,
}
}