개발/Go

[Gin] GORM 필드 유효성 검사 + Validator 연동하기

devhooney 2025. 6. 27. 08:07
728x90

Go는 정적 타입 언어지만, API 개발을 하다 보면 요청 데이터에 대한 유효성 검사(validation) 가 꼭 필요하다.
GORM만 써서는 해결되지 않는 입력값 검증은 validator 라이브러리와 함께 처리하는 것이 일반적이다.

이번 포스팅에서는 실전에서 가장 많이 쓰이는 유효성 검사 라이브러리인 go-playground/validator와 GORM 모델을 함께 사용하는 방법을 다룬다.

 


 

 

 

728x90

 

 

 

✅ 1. Validator 설치하기

go get github.com/go-playground/validator/v10

 

 

 

 


 

 

 

✅ 2. 기본 사용법

import (
    "github.com/go-playground/validator/v10"
)

type User struct {
    Name  string `validate:"required"`
    Email string `validate:"required,email"`
    Age   int    `validate:"gte=0,lte=130"`
}

func main() {
    validate := validator.New()

    user := User{
        Name:  "John",
        Email: "invalid-email",
        Age:   200,
    }

    err := validate.Struct(user)
    if err != nil {
        for _, err := range err.(validator.ValidationErrors) {
            fmt.Println("Field:", err.Field(), "Error:", err.Tag())
        }
    }
}

 

 

 

 

 


 

 

✅ 3. GORM 모델에 적용하기

GORM 모델에 validate 태그를 추가해서 요청 바인딩 시 검증할 수 있다.

예제 모델

type SignUpInput struct {
    Name     string `json:"name" validate:"required,min=2,max=20"`
    Email    string `json:"email" validate:"required,email"`
    Password string `json:"password" validate:"required,min=8"`
}

 

 

 


 

 

✅ 4. Gin과 함께 쓰기 — Request 바인딩과 유효성 검사

Gin에서는 ShouldBindJSON()과 함께 validator를 연동하면 깔끔하게 처리할 수 있다.

예제 핸들러

func SignUpHandler(c *gin.Context) {
    var input SignUpInput
    if err := c.ShouldBindJSON(&input); err != nil {
        c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request"})
        return
    }

    validate := validator.New()
    if err := validate.Struct(input); err != nil {
        errs := err.(validator.ValidationErrors)
        messages := make([]string, 0)
        for _, e := range errs {
            messages = append(messages, fmt.Sprintf("%s is %s", e.Field(), e.Tag()))
        }
        c.JSON(http.StatusBadRequest, gin.H{"errors": messages})
        return
    }

    // 유효성 통과 → DB 저장
    user := User{Name: input.Name, Email: input.Email, Password: input.Password}
    if err := db.Create(&user).Error; err != nil {
        c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to create user"})
        return
    }

    c.JSON(http.StatusOK, gin.H{"message": "User created"})
}

 

 

 


 

 

✅ 5. 커스텀 Validation 만들기

필요에 따라 커스텀 검증 로직도 쉽게 추가할 수 있다.

validate := validator.New()
validate.RegisterValidation("is-cool", func(fl validator.FieldLevel) bool {
    return fl.Field().String() == "cool"
})

type CoolInput struct {
    Nickname string `validate:"is-cool"`
}




 

✅ 6. 응답 메시지 다국어 처리 (선택)

Validator는 Universal Translator를 통해 다국어 에러 메시지도 제공할 수 있다.
실무에서 사용자에게 친절한 메시지를 보여주려면 고려해볼만 하다.

 

 

 

 


 

 

✅ 실무 팁 요약

항목 설명
validate:"required" 필수값 검증
validate:"email" 이메일 형식 검증
validate:"min=8" 문자열 길이 최소값
validate:"gte=0" 숫자 이상값 (greater than or equal)
RegisterValidation() 커스텀 태그 추가 가능
Universal Translator 다국어 메시지 처리 가능 (선택)

 

 

 

 

 

 

 

 

728x90