mirror of
https://github.com/rjNemo/go-microservices-tuto
synced 2026-06-12 13:26:45 +00:00
get all products
This commit is contained in:
commit
7d6ca2d8eb
6 changed files with 148 additions and 0 deletions
3
go.mod
Normal file
3
go.mod
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
module github.com/rjNemo/go-micro
|
||||||
|
|
||||||
|
go 1.14
|
||||||
1
go.sum
Normal file
1
go.sum
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
golang.org/x/tools v0.0.0-20200713195033-f8240f79c3d3 h1:xV8QVipADSbgfDrrjnUyOJILDkpbFpyoLV4x06POJ7I=
|
||||||
27
handlers/products.go
Normal file
27
handlers/products.go
Normal 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
45
main.go
Normal 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
55
products/data/product.go
Normal 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
17
server/server.go
Normal 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,
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue