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