diff --git a/src/frontend/handlers.go b/src/frontend/handlers.go
index 5e23301..67f6c1b 100644
--- a/src/frontend/handlers.go
+++ b/src/frontend/handlers.go
@@ -8,6 +8,7 @@ import (
"net/http"
"github.com/google/uuid"
+ "github.com/gorilla/mux"
pb "frontend/genproto"
)
@@ -54,8 +55,7 @@ func (fe *frontendServer) homeHandler(w http.ResponseWriter, r *http.Request) {
log.Printf("[home] session_id=%+v", r.Context().Value(ctxKeySessionID{}))
currencies, err := fe.getCurrencies(r.Context())
if err != nil {
- log.Println(err) // TODO(ahmetb) use structured logging
- w.WriteHeader(http.StatusInternalServerError)
+ http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
log.Printf("currencies: %+v", currencies)
@@ -92,6 +92,47 @@ func (fe *frontendServer) homeHandler(w http.ResponseWriter, r *http.Request) {
}
}
+func (fe *frontendServer) productHandler(w http.ResponseWriter, r *http.Request) {
+ id := mux.Vars(r)["id"]
+ if id == "" {
+ http.Error(w, "product id not specified", http.StatusBadRequest)
+ return
+ }
+ log.Printf("[productHandler] id=%s", id)
+ p, err := fe.getProduct(r.Context(), id)
+ if err != nil {
+ http.Error(w, fmt.Sprintf("could not retrieve product: %+v", err), http.StatusInternalServerError)
+ return
+ }
+
+ currencies, err := fe.getCurrencies(r.Context())
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+
+ price, err := fe.convertCurrency(r.Context(), &pb.Money{
+ Amount: p.GetPriceUsd(),
+ CurrencyCode: defaultCurrency}, currentCurrency(r))
+ if err != nil {
+ http.Error(w, fmt.Sprintf("failed to convert currency: %+v", err), http.StatusInternalServerError)
+ return
+ }
+
+ product := struct {
+ Item *pb.Product
+ Price *pb.Money
+ }{p, price}
+
+ if err := templates.ExecuteTemplate(w, "product", map[string]interface{}{
+ "user_currency": currentCurrency(r),
+ "currencies": currencies,
+ "product": product,
+ }); err != nil {
+ log.Println(err)
+ }
+}
+
func (fe *frontendServer) logoutHandler(w http.ResponseWriter, r *http.Request) {
log.Printf("[home] session_id=%+v", r.Context().Value(ctxKeySessionID{}))
for _, c := range r.Cookies() {
diff --git a/src/frontend/main.go b/src/frontend/main.go
index 48db535..cc17a50 100644
--- a/src/frontend/main.go
+++ b/src/frontend/main.go
@@ -64,16 +64,16 @@ func main() {
r := mux.NewRouter()
r.HandleFunc("/", refreshCookies(
ensureSessionID(
- svc.homeHandler))).
- Methods(http.MethodGet, http.MethodHead)
+ svc.homeHandler))).Methods(http.MethodGet, http.MethodHead)
+ r.HandleFunc("/product/{id}", refreshCookies(
+ ensureSessionID(
+ svc.productHandler))).Methods(http.MethodGet, http.MethodHead)
r.PathPrefix("/static/").Handler(http.StripPrefix("/static/",
http.FileServer(http.Dir("./static/"))))
- r.HandleFunc("/logout", svc.logoutHandler).
- Methods(http.MethodGet)
+ r.HandleFunc("/logout", svc.logoutHandler).Methods(http.MethodGet)
r.HandleFunc("/setCurrency", refreshCookies(
ensureSessionID(
- svc.setCurrencyHandler))).
- Methods(http.MethodPost)
+ svc.setCurrencyHandler))).Methods(http.MethodPost)
log.Printf("starting server on :" + srvPort)
log.Fatal(http.ListenAndServe("localhost:"+srvPort, r))
}
diff --git a/src/frontend/rpc.go b/src/frontend/rpc.go
index 5d31b1b..1a08956 100644
--- a/src/frontend/rpc.go
+++ b/src/frontend/rpc.go
@@ -31,6 +31,12 @@ func (fe *frontendServer) getProducts(ctx context.Context) ([]*pb.Product, error
return resp.GetProducts(), err
}
+func (fe *frontendServer) getProduct(ctx context.Context, id string) (*pb.Product, error) {
+ resp, err := pb.NewProductCatalogServiceClient(fe.productCatalogSvcConn).
+ GetProduct(ctx, &pb.GetProductRequest{Id: id})
+ return resp, err
+}
+
func (fe *frontendServer) convertCurrency(ctx context.Context, money *pb.Money, currency string) (*pb.Money, error) {
if avoidNoopCurrencyConversionRPC && money.GetCurrencyCode() == currency {
return money, nil
diff --git a/src/frontend/templates/home.html b/src/frontend/templates/home.html
index e871634..b8c8dd9 100644
--- a/src/frontend/templates/home.html
+++ b/src/frontend/templates/home.html
@@ -16,22 +16,26 @@
-
+
{{ range $.products }}
-
+
+
+
{{ .Item.Name }}
{{.Price.CurrencyCode}}
diff --git a/src/frontend/templates/product.html b/src/frontend/templates/product.html
new file mode 100644
index 0000000..724ca9c
--- /dev/null
+++ b/src/frontend/templates/product.html
@@ -0,0 +1,52 @@
+{{ define "product" }}
+ {{ template "header" . }}
+
+
+
+
+
+
+
+
+
+
{{$.product.Item.Name}}
+
+
+ {{$.product.Price.CurrencyCode}}
+ {{$.product.Price.Amount.Decimal}}.
+ {{- $.product.Price.Amount.Fractional}}{{- if lt $.product.Price.Amount.Fractional 10}}0{{end}}
+
+
+
+
Product Description:
+ {{$.product.Item.Description}}
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ template "footer" . }}
+{{ end }}