github.com/shoshinnikita/budget-manager@v0.7.1-0.20220131195411-8c46ff1c6778/internal/web/utils/decode.go (about) 1 package utils 2 3 import ( 4 "encoding/json" 5 "io" 6 "net/http" 7 "net/url" 8 9 "github.com/ShoshinNikita/budget-manager/internal/logger" 10 "github.com/ShoshinNikita/budget-manager/internal/pkg/errors" 11 "github.com/ShoshinNikita/budget-manager/internal/web/utils/schema" 12 ) 13 14 type Request interface { 15 SanitizeAndCheck() error 16 } 17 18 // DecodeRequest decodes request and checks its validity. It process error if needed 19 func DecodeRequest(w http.ResponseWriter, r *http.Request, log logger.Logger, req Request) (ok bool) { 20 ctx := r.Context() 21 22 if err := r.ParseForm(); err != nil { 23 EncodeError(ctx, w, log, errors.Wrap(err, "couldn't parse form"), http.StatusBadRequest) 24 return false 25 } 26 27 var err error 28 switch r.Method { 29 case http.MethodGet, http.MethodHead: 30 err = decodeQueryRequest(r.Form, req) 31 default: 32 err = decodeJSONRequest(r.Body, req) 33 } 34 if err != nil { 35 EncodeError(ctx, w, log, errors.Wrap(err, "couldn't decode request"), http.StatusBadRequest) 36 return false 37 } 38 39 if err := req.SanitizeAndCheck(); err != nil { 40 EncodeError(ctx, w, log, err, http.StatusBadRequest) 41 return false 42 } 43 44 return true 45 } 46 47 func decodeJSONRequest(body io.Reader, req interface{}) error { 48 decoder := json.NewDecoder(body) 49 decoder.DisallowUnknownFields() 50 return decoder.Decode(req) 51 } 52 53 func decodeQueryRequest(form url.Values, req interface{}) error { 54 return schema.Decode(req, form) 55 }