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