From e854f2e81fc1ed032a1e9b3b81daff0626976831 Mon Sep 17 00:00:00 2001 From: nochill Date: Wed, 13 Sep 2023 11:30:15 +0700 Subject: [PATCH] refactor validation error and user register response --- api/BaseResponse.go | 40 ++++++++++++++++++++++++++++++++- api/user.go | 54 ++++++++++++++------------------------------- 2 files changed, 55 insertions(+), 39 deletions(-) diff --git a/api/BaseResponse.go b/api/BaseResponse.go index 2444442..a623726 100644 --- a/api/BaseResponse.go +++ b/api/BaseResponse.go @@ -1,6 +1,44 @@ package api -import "github.com/gin-gonic/gin" +import ( + "errors" + "fmt" + + "github.com/gin-gonic/gin" + "github.com/go-playground/validator/v10" +) + +type APIValidationError struct { + Field string `json:"field"` + Msg string `json:"msg"` +} + +func validationErrorMsg(field string, param string, tag string) string { + switch tag { + case "min": + return fmt.Sprintf("%s character min %s", field, param) + case "required": + return fmt.Sprintf("%s is %s", field, tag) + default: + return fmt.Sprintf("%s %s", field, tag) + } +} + +func ValidationErrorResponse(err error) gin.H { + var ves validator.ValidationErrors + var temp []APIValidationError + if errors.As(err, &ves) { + out := make([]APIValidationError, len(ves)) + for i, ve := range ves { + out[i] = APIValidationError{ve.Field(), validationErrorMsg(ve.Field(), ve.Param(), ve.ActualTag())} + } + temp = out + } + return gin.H{ + "message": "Validation error", + "errors": temp, + } +} func ErrorResponse(err error, msg string) gin.H { return gin.H{ diff --git a/api/user.go b/api/user.go index 61452e4..f531489 100644 --- a/api/user.go +++ b/api/user.go @@ -2,14 +2,12 @@ package api import ( "database/sql" - "errors" - "fmt" "net/http" + "time" db "git.nochill.in/nochill/hiling_go/db/sqlc" "git.nochill.in/nochill/hiling_go/util" "github.com/gin-gonic/gin" - "github.com/go-playground/validator/v10" "github.com/lib/pq" ) @@ -25,40 +23,19 @@ type createUserResponse struct { BannedAt sql.NullTime `json:"banned_at"` BannedUntil sql.NullTime `json:"banned_until"` BanReason string `json:"ban_reason"` - IsPermaban sql.NullBool `json:"is_permaban"` - IsAdmin sql.NullBool `json:"is_admin"` - IsCritics sql.NullBool `json:"is_critics"` - IsVerified sql.NullBool `json:"is_verified"` - CreatedAt sql.NullTime `json:"created_at"` - UpdatedAt sql.NullTime `json:"updated_at"` -} - -type ApiError struct { - Field string - Msg string -} - -func msgForTag(field string, param string, tag string) string { - switch tag { - case "min": - return fmt.Sprintf("%s character min %s", field, param) - default: - return fmt.Sprintf("%s %s", field, tag) - } + IsPermaban bool `json:"is_permaban"` + IsAdmin bool `json:"is_admin"` + IsCritics bool `json:"is_critics"` + IsVerified bool `json:"is_verified"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` } func (server *Server) createUser(ctx *gin.Context) { var req createUserRequest if err := ctx.ShouldBindJSON(&req); err != nil { if err != nil { - var ve validator.ValidationErrors - if errors.As(err, &ve) { - out := make([]ApiError, len(ve)) - for i, fe := range ve { - out[i] = ApiError{fe.Field(), msgForTag(fe.Field(), fe.Param(), fe.Tag())} - } - ctx.JSON(http.StatusBadRequest, gin.H{"errors": out}) - } + ctx.JSON(http.StatusBadRequest, ValidationErrorResponse(err)) return } } @@ -79,7 +56,8 @@ func (server *Server) createUser(ctx *gin.Context) { if pqErr, ok := err.(*pq.Error); ok { switch pqErr.Code.Name() { case "foreign_key_violation", "unique_violation": - ctx.JSON(http.StatusConflict, ErrorResponse(err, "Something went wrong while try to save")) + ctx.JSON(http.StatusConflict, ErrorResponse(err, "Username already used")) + return } } @@ -94,12 +72,12 @@ func (server *Server) createUser(ctx *gin.Context) { BannedAt: sql.NullTime{Valid: user.BannedAt.Valid, Time: user.BannedAt.Time}, BannedUntil: sql.NullTime{Valid: user.BannedUntil.Valid, Time: user.BannedUntil.Time}, BanReason: user.BanReason.String, - IsPermaban: user.IsPermaban, - IsAdmin: user.IsAdmin, - IsCritics: user.IsCritics, - IsVerified: user.IsVerified, - CreatedAt: sql.NullTime{Valid: true, Time: user.CreatedAt.Time}, - UpdatedAt: sql.NullTime{Valid: true, Time: user.UpdatedAt.Time}, + IsPermaban: user.IsPermaban.Bool, + IsAdmin: user.IsAdmin.Bool, + IsCritics: user.IsCritics.Bool, + IsVerified: user.IsVerified.Bool, + CreatedAt: user.CreatedAt.Time, + UpdatedAt: user.UpdatedAt.Time, } ctx.JSON(http.StatusOK, res)