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  }