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 }