github.com/timoth-y/kicksware-api/order-service@v0.0.0-20201002192818-87b546a7ae5a/api/rest/handler.go (about)

     1  package rest
     2  
     3  import (
     4  	"io/ioutil"
     5  	"log"
     6  	"net/http"
     7  
     8  	"github.com/go-chi/chi"
     9  	"github.com/pkg/errors"
    10  	"github.com/timoth-y/kicksware-api/service-common/util"
    11  
    12  	"github.com/timoth-y/kicksware-api/service-common/core/meta"
    13  
    14  	"github.com/timoth-y/kicksware-api/order-service/core/model"
    15  	"github.com/timoth-y/kicksware-api/order-service/core/service"
    16  	"github.com/timoth-y/kicksware-api/order-service/env"
    17  	"github.com/timoth-y/kicksware-api/order-service/usecase/business"
    18  	"github.com/timoth-y/kicksware-api/order-service/usecase/serializer/json"
    19  	"github.com/timoth-y/kicksware-api/order-service/usecase/serializer/msg"
    20  )
    21  
    22  type Handler struct {
    23  	service     service.OrderService
    24  	auth        service.AuthService
    25  	contentType string
    26  }
    27  
    28  func NewHandler(service service.OrderService, auth service.AuthService, config env.CommonConfig) *Handler {
    29  	return &Handler{
    30  		service,
    31  		auth,
    32  		config.ContentType,
    33  	}
    34  }
    35  
    36  func (h *Handler) GetOne(w http.ResponseWriter, r *http.Request) {
    37  	code := chi.URLParam(r,"orderID")
    38  	params := NewRequestParams(r)
    39  	order, err := h.service.FetchOne(code, params)
    40  	if err != nil {
    41  		if errors.Cause(err) == business.ErrOrderNotFound {
    42  			http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
    43  			return
    44  		}
    45  		http.Error(w, err.Error(), http.StatusInternalServerError)
    46  		return
    47  	}
    48  	h.setupResponse(w, order, http.StatusOK)
    49  }
    50  
    51  func (h *Handler) Get(w http.ResponseWriter, r *http.Request) {
    52  	var orders []*model.Order
    53  	var err error
    54  	params := NewRequestParams(r)
    55  
    56  	if r.Method == http.MethodPost {
    57  		query, err := h.getRequestQuery(r); if err != nil {
    58  			http.Error(w, err.Error(), http.StatusBadRequest)
    59  			return
    60  		}
    61  		orders, err = h.service.FetchQuery(query, params)
    62  	} else if r.Method == http.MethodGet {
    63  		codes := r.URL.Query()["orderID"]
    64  		if codes != nil && len(codes) > 0 {
    65  			orders, err = h.service.Fetch(codes, params)
    66  		} else {
    67  			orders, err = h.service.FetchAll(params)
    68  		}
    69  	}
    70  
    71  	if err != nil {
    72  		if errors.Cause(err) == business.ErrOrderNotFound {
    73  			http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
    74  			return
    75  		}
    76  		http.Error(w, err.Error(), http.StatusInternalServerError)
    77  		return
    78  	}
    79  	h.setupResponse(w, orders, http.StatusOK)
    80  }
    81  
    82  func (h *Handler) PostOne(w http.ResponseWriter, r *http.Request) {
    83  	order, err := h.getRequestBody(r)
    84  	if err != nil {
    85  		http.Error(w, err.Error(), http.StatusBadRequest)
    86  		return
    87  	}
    88  	err = h.service.StoreOne(order)
    89  	if err != nil {
    90  		if errors.Cause(err) == business.ErrOrderNotValid {
    91  			http.Error(w, err.Error(), http.StatusBadRequest)
    92  			return
    93  		}
    94  		http.Error(w, err.Error(), http.StatusInternalServerError)
    95  		return
    96  	}
    97  	h.setupResponse(w, order, http.StatusOK)
    98  }
    99  
   100  func (h *Handler) Post(w http.ResponseWriter, r *http.Request) {
   101  	order, err := h.getRequestBody(r)
   102  	if err != nil {
   103  		http.Error(w, err.Error(), http.StatusInternalServerError)
   104  		return
   105  	}
   106  	err = h.service.StoreOne(order)
   107  	if err != nil {
   108  		if errors.Cause(err) == business.ErrOrderNotValid {
   109  			http.Error(w, err.Error(), http.StatusBadRequest)
   110  			return
   111  		}
   112  		http.Error(w, err.Error(), http.StatusInternalServerError)
   113  		return
   114  	}
   115  	h.setupResponse(w, order, http.StatusOK)
   116  }
   117  
   118  
   119  func (h *Handler) Patch(w http.ResponseWriter, r *http.Request) {
   120  	order, err := h.getRequestBody(r)
   121  	if err != nil {
   122  		http.Error(w, err.Error(), http.StatusInternalServerError)
   123  		return
   124  	}
   125  	err = h.service.Modify(order)
   126  	if err != nil {
   127  		if errors.Cause(err) == business.ErrOrderNotValid {
   128  			http.Error(w, err.Error(), http.StatusBadRequest)
   129  			return
   130  		}
   131  		http.Error(w, err.Error(), http.StatusInternalServerError)
   132  		return
   133  	}
   134  	h.setupResponse(w, nil, http.StatusOK)
   135  }
   136  
   137  func (h *Handler) Count(w http.ResponseWriter, r *http.Request) {
   138  	var count int
   139  	var err error
   140  	params := NewRequestParams(r)
   141  
   142  	if r.Method == http.MethodPost {
   143  		query, err := h.getRequestQuery(r)
   144  		if err != nil {
   145  			http.Error(w, err.Error(), http.StatusBadRequest)
   146  			return
   147  		}
   148  		count, err = h.service.Count(query, params)
   149  	} else if r.Method == http.MethodGet {
   150  		query := r.URL.Query()
   151  		if query != nil && len(query) > 0 {
   152  			count, err = h.service.Count(util.ToQueryMap(query), params)
   153  		} else {
   154  			count, err = h.service.CountAll()
   155  		}
   156  	}
   157  
   158  	if err != nil {
   159  		if errors.Cause(err) == business.ErrOrderNotFound {
   160  			h.setupResponse(w, 0, http.StatusOK)
   161  			return
   162  		}
   163  		http.Error(w, err.Error(), http.StatusInternalServerError)
   164  		return
   165  	}
   166  	h.setupResponse(w, count, http.StatusOK)
   167  }
   168  
   169  func (h *Handler) setupResponse(w http.ResponseWriter, body interface{}, statusCode int) {
   170  	w.Header().Set("Content-Type", h.contentType)
   171  	w.WriteHeader(statusCode)
   172  	if body != nil {
   173  		raw, err := h.serializer(h.contentType).Encode(body)
   174  		if err != nil {
   175  			http.Error(w, err.Error(), http.StatusInternalServerError)
   176  			return
   177  		}
   178  		if _, err := w.Write(raw); err != nil {
   179  			log.Println(err)
   180  		}
   181  	}
   182  }
   183  
   184  func (h *Handler) getRequestQuery(r *http.Request) (meta.RequestQuery, error) {
   185  	contentType := r.Header.Get("Content-Type")
   186  	requestBody, err := ioutil.ReadAll(r.Body)
   187  	if err != nil {
   188  		return nil, err
   189  	}
   190  	body, err := h.serializer(contentType).DecodeMap(requestBody)
   191  	if err != nil {
   192  		return nil, err
   193  	}
   194  	return body, nil
   195  }
   196  
   197  func (h *Handler) getRequestBody(r *http.Request) (*model.Order, error) {
   198  	contentType := r.Header.Get("Content-Type")
   199  	requestBody, err := ioutil.ReadAll(r.Body)
   200  	if err != nil {
   201  		return nil, err
   202  	}
   203  	body, err := h.serializer(contentType).Decode(requestBody)
   204  	if err != nil {
   205  		return nil, err
   206  	}
   207  	return body, nil
   208  }
   209  
   210  
   211  func (h *Handler) getRequestBodies(r *http.Request) ([]*model.Order, error) {
   212  	contentType := r.Header.Get("Content-Type")
   213  	requestBody, err := ioutil.ReadAll(r.Body)
   214  	if err != nil {
   215  		return nil, err
   216  	}
   217  	bodies, err := h.serializer(contentType).DecodeRange(requestBody)
   218  	if err != nil {
   219  		return nil, err
   220  	}
   221  	return bodies, nil
   222  }
   223  
   224  func (h *Handler) serializer(contentType string) service.OrderSerializer {
   225  	if contentType == "application/x-msgpack" {
   226  		return msg.NewSerializer()
   227  	}
   228  	return json.NewSerializer()
   229  }