1package tracking
2
3import (
4	"context"
5	"encoding/json"
6	"errors"
7	"net/http"
8
9	"github.com/gorilla/mux"
10
11	kitlog "github.com/go-kit/kit/log"
12	kittransport "github.com/go-kit/kit/transport"
13	kithttp "github.com/go-kit/kit/transport/http"
14
15	"github.com/go-kit/kit/examples/shipping/cargo"
16)
17
18// MakeHandler returns a handler for the tracking service.
19func MakeHandler(ts Service, logger kitlog.Logger) http.Handler {
20	r := mux.NewRouter()
21
22	opts := []kithttp.ServerOption{
23		kithttp.ServerErrorHandler(kittransport.NewLogErrorHandler(logger)),
24		kithttp.ServerErrorEncoder(encodeError),
25	}
26
27	trackCargoHandler := kithttp.NewServer(
28		makeTrackCargoEndpoint(ts),
29		decodeTrackCargoRequest,
30		encodeResponse,
31		opts...,
32	)
33
34	r.Handle("/tracking/v1/cargos/{id}", trackCargoHandler).Methods("GET")
35
36	return r
37}
38
39func decodeTrackCargoRequest(_ context.Context, r *http.Request) (interface{}, error) {
40	vars := mux.Vars(r)
41	id, ok := vars["id"]
42	if !ok {
43		return nil, errors.New("bad route")
44	}
45	return trackCargoRequest{ID: id}, nil
46}
47
48func encodeResponse(ctx context.Context, w http.ResponseWriter, response interface{}) error {
49	if e, ok := response.(errorer); ok && e.error() != nil {
50		encodeError(ctx, e.error(), w)
51		return nil
52	}
53	w.Header().Set("Content-Type", "application/json; charset=utf-8")
54	return json.NewEncoder(w).Encode(response)
55}
56
57type errorer interface {
58	error() error
59}
60
61// encode errors from business-logic
62func encodeError(_ context.Context, err error, w http.ResponseWriter) {
63	w.Header().Set("Content-Type", "application/json; charset=utf-8")
64	switch err {
65	case cargo.ErrUnknown:
66		w.WriteHeader(http.StatusNotFound)
67	case ErrInvalidArgument:
68		w.WriteHeader(http.StatusBadRequest)
69	default:
70		w.WriteHeader(http.StatusInternalServerError)
71	}
72	json.NewEncoder(w).Encode(map[string]interface{}{
73		"error": err.Error(),
74	})
75}
76