From 91e7259828a06003739b29af48acdd8e5c9172ef Mon Sep 17 00:00:00 2001 From: kubitre Date: Sun, 13 Feb 2022 03:03:03 +0700 Subject: [PATCH] fixed and enahnced request extractor --- Readme.md | 2 +- extractors/extract_request.go | 16 ++++++++++++++-- .../metrics_middleware.go | 10 ++++------ 3 files changed, 19 insertions(+), 9 deletions(-) rename {middlewares => metrics_prometheus}/metrics_middleware.go (69%) diff --git a/Readme.md b/Readme.md index a94f2bf..074dac5 100644 --- a/Readme.md +++ b/Readme.md @@ -9,7 +9,7 @@ Infrastructre methods and types for make api simple ## Request -- extract body to data class from all sources request with special tag +- extract body to data class from all sources request with special tag and automatic response build (not best practic copy and paste deserialize code) ## Metrics Prometheus diff --git a/extractors/extract_request.go b/extractors/extract_request.go index 9b9ef0b..f48ac4a 100644 --- a/extractors/extract_request.go +++ b/extractors/extract_request.go @@ -6,6 +6,7 @@ import ( "net/http" "reflect" + "github.com/kubitre/go_api_infra/response" "github.com/spf13/cast" ) @@ -20,10 +21,18 @@ const ( type extractor func(string, *http.Request) interface{} -func RequestToType(request *http.Request, data interface{}, tartgetParamsPlaces ...ParserType) (interface{}, error) { +/** +RequestToType - extract from http.Request payload data from: +1. Body (prefer) +2. PathVariables(optional) +3. QueryParams(optional) +4. Headers(optional) +*/ +func RequestToType(request *http.Request, writer http.ResponseWriter, target string, data interface{}, tartgetParamsPlaces ...ParserType) (interface{}, error) { if err := json.NewDecoder(request.Body).Decode(&data); err != nil { if len(tartgetParamsPlaces) == 0 { - return nil, errors.New("can not unmarshalled request") + response.NewResponseJSON(writer, target).BadRequest(response.ApiError{Code: "WEB_INPUT_ERROR", Message: "can not deserialize input request", Target: target, Context: "Read spec at: /swagger"}) + return nil, err } } @@ -43,6 +52,9 @@ func RequestToType(request *http.Request, data interface{}, tartgetParamsPlaces value := reflect.Indirect(reflect.ValueOf(data)) if err := prepareInlineStructFields(request, value, extractorFuncs); err != nil { + response.NewResponseJSON(writer, target).BadRequest( + response.ApiError{Code: "WEB_INPUT_ERROR", Message: "can not deserialize input request", Target: target, Context: "Read spec at: /swagger"}, + ) return nil, err } diff --git a/middlewares/metrics_middleware.go b/metrics_prometheus/metrics_middleware.go similarity index 69% rename from middlewares/metrics_middleware.go rename to metrics_prometheus/metrics_middleware.go index 41d6dc8..31216c2 100644 --- a/middlewares/metrics_middleware.go +++ b/metrics_prometheus/metrics_middleware.go @@ -1,14 +1,12 @@ -package middlewares +package metricsprometheus import ( "net/http" "strconv" "time" - - metricsprometheus "github.com/kubitre/go_api_infra/metrics_prometheus" ) -func AddGoldenMetrics(recorder metricsprometheus.MetricRecorder, method string, handler http.HandlerFunc) http.Handler { +func AddGoldenMetrics(recorder MetricRecorder, method string, handler http.HandlerFunc) http.Handler { return http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) { wi := &responseWriterInterceptor{ statusCode: http.StatusOK, @@ -17,12 +15,12 @@ func AddGoldenMetrics(recorder metricsprometheus.MetricRecorder, method string, timeStart := time.Now() defer func() { - recorder.ObserveHTTPRequestDuration(request.Context(), metricsprometheus.HTTPReqProperties{ + recorder.ObserveHTTPRequestDuration(request.Context(), HTTPReqProperties{ Method: method, Code: strconv.Itoa(wi.statusCode), }, time.Since(timeStart)) - recorder.ObserveHTTPResponseSize(request.Context(), metricsprometheus.HTTPReqProperties{ + recorder.ObserveHTTPResponseSize(request.Context(), HTTPReqProperties{ Method: method, Code: strconv.Itoa(wi.statusCode), }, wi.sizeResponse)