github.com/lovung/GoCleanArchitecture@v0.0.0-20210302152432-50d91fd29f9f/app/internal/interface/restful/middleware/json_writer_middleware.go (about) 1 package middleware 2 3 import ( 4 "net/http" 5 6 "github.com/lovung/GoCleanArchitecture/app/internal/appctx" 7 "github.com/lovung/GoCleanArchitecture/app/internal/interface/restful/presenter" 8 9 "github.com/gin-gonic/gin" 10 "github.com/go-playground/validator/v10" 11 ) 12 13 // JSONWriterMiddleware follow jsonapi.org 14 // Respond check errors, prepare meta and respond data 15 func JSONWriterMiddleware(ctx *gin.Context) { 16 ctx.Next() 17 18 // Check error if exists 19 // Base on error/success to return meta object 20 var ( 21 res presenter.Response 22 httpCode int 23 ) 24 appErr := appctx.GetValue(ctx.Request.Context(), appctx.ErrorContextKey) 25 if appErr != nil { 26 _processAppError(&res, appErr) 27 httpCode = res.Meta.Code 28 } 29 30 // Respond the data object/array 31 data := appctx.GetValue(ctx.Request.Context(), appctx.DataContextKey) 32 if data != nil { 33 res.Data = data 34 } 35 meta := appctx.GetValue(ctx.Request.Context(), appctx.MetaContextKey) 36 if meta != nil { 37 metaRes, ok1 := meta.(presenter.MetaResponse) 38 if ok1 { 39 res.Meta = metaRes 40 httpCode = metaRes.Code 41 } 42 } 43 if res.IsEmpty() { 44 ctx.JSON(http.StatusNoContent, nil) 45 } else { 46 ctx.JSON(httpCode, res) 47 } 48 } 49 50 func _processAppError(res *presenter.Response, appErr interface{}) { 51 bindingErr := _catchBindingError(appErr.(error)) 52 if bindingErr != nil { 53 res.Errors = bindingErr.(presenter.ErrorResponses) 54 res.Meta = presenter.MetaResponse{ 55 Code: http.StatusBadRequest, 56 Message: "error when binding the request", 57 } 58 } 59 } 60 61 func _catchBindingError(appErr error) error { 62 var errs presenter.ErrorResponses 63 if _, ok := appErr.(*validator.InvalidValidationError); ok { 64 errs.Append(presenter.ErrorResponse{ 65 Code: http.StatusInternalServerError, 66 Detail: "invalid validation error", 67 }) 68 return errs 69 } 70 71 if vldrErr, ok := appErr.(validator.ValidationErrors); ok { 72 errs.FromValidationErrors(vldrErr) 73 return errs 74 } 75 76 return nil 77 }