package tracking import ( "context" "encoding/json" "errors" "net/http" "github.com/gorilla/mux" kitlog "github.com/go-kit/kit/log" kittransport "github.com/go-kit/kit/transport" kithttp "github.com/go-kit/kit/transport/http" "github.com/go-kit/kit/examples/shipping/cargo" ) // MakeHandler returns a handler for the tracking service. func MakeHandler(ts Service, logger kitlog.Logger) http.Handler { r := mux.NewRouter() opts := []kithttp.ServerOption{ kithttp.ServerErrorHandler(kittransport.NewLogErrorHandler(logger)), kithttp.ServerErrorEncoder(encodeError), } trackCargoHandler := kithttp.NewServer( makeTrackCargoEndpoint(ts), decodeTrackCargoRequest, encodeResponse, opts..., ) r.Handle("/tracking/v1/cargos/{id}", trackCargoHandler).Methods("GET") return r } func decodeTrackCargoRequest(_ context.Context, r *http.Request) (interface{}, error) { vars := mux.Vars(r) id, ok := vars["id"] if !ok { return nil, errors.New("bad route") } return trackCargoRequest{ID: id}, nil } func encodeResponse(ctx context.Context, w http.ResponseWriter, response interface{}) error { if e, ok := response.(errorer); ok && e.error() != nil { encodeError(ctx, e.error(), w) return nil } w.Header().Set("Content-Type", "application/json; charset=utf-8") return json.NewEncoder(w).Encode(response) } type errorer interface { error() error } // encode errors from business-logic func encodeError(_ context.Context, err error, w http.ResponseWriter) { w.Header().Set("Content-Type", "application/json; charset=utf-8") switch err { case cargo.ErrUnknown: w.WriteHeader(http.StatusNotFound) case ErrInvalidArgument: w.WriteHeader(http.StatusBadRequest) default: w.WriteHeader(http.StatusInternalServerError) } json.NewEncoder(w).Encode(map[string]interface{}{ "error": err.Error(), }) }