회사에서 Gin을 쓰다가 struct 단에서의 Validation을 하려는데 gin context에서 binding을 할 때 쓰는 거에 따라서 결과가 달라서 정리를 해본다.
보통 body로 들어오는 요청을 처리하는 struct는 아래와 같이 구성한다.
type Bind struct {
Name string `json:"name"`
}
여기서 만약 해당 struct로 body 값을 파싱하려면 아래와 같이 할 수 있다.
r.POST("/", func(c *gin.Context) {
req := &Bind{}
err := c.Bind(req)
if err != nil {
c.JSON(http.StatusBadRequest, err.Error())
return
}
c.Status(http.StatusOK)
})
이때 현재 코드대로 하면 name 값이 안들어와도 에러 처리가 되지 않는다.
name 값이 optional 하다면 그대로 하면 되겠지만 필수라면 어떻게 처리가 가능할까?
간단하게 struct에서 binding:"required"를 추가하면 된다.
type Bind struct {
Name string `json:"name" binding:"required"`
}
이렇게 Bind를 사용해서 binding:"required"와 같이 처리한다면 name 값이 안들어올시에 400 에러가 바로 처리된다.
만약 바로 처리되는게 싫고 따로 커스터마이징 하고싶다면 Bind 대신 ShouldBind 를 사용하면 된다.
r.POST("/", func(c *gin.Context) {
req := &Bind{}
err := c.ShouldBind(req)
if err != nil {
c.JSON(http.StatusBadRequest, err.Error())
return
}
c.Status(http.StatusOK)
})
이러면 이제 err 처리 부분이 없다면 name 값이 안들어와도 통과되어 200이 나게 된다.
정리하자면
ShouldBind + binding:"required"
err만 return하고 따로 response까지 날려주진 않음. -> error 처리하는 부분이 없다면 아래 flow 그대로 실행
Bind + binding:"required"
err가 바로 남 -> 따로 err 를 받지 않고도 400 에러가 바로 남. -> 에러 처리하는 부분이 없어도 400 status code를 반환한다.
ShouldBind 만 있으면
에러가 잡히지 않음
Bind 만 있으면
에러가 잡히지 않음
상황에 맞게 쓰면 될거같다.
추가로 param와 query도 파싱할 경우가 생기는데 아래처럼 하면 된다.
Param
type Bind struct {
Name string `uri:"name" binding:"required"`
}
r.POST("/:name", func(c *gin.Context) {
req := &Bind{}
err := c.BindUri(req)
if err != nil {
c.JSON(http.StatusBadRequest, err.Error())
return
}
c.Status(http.StatusOK)
})
Query
type Bind struct {
Name string `form:"name" binding:"required"`
}
r.GET("/", func(c *gin.Context) {
req := &Bind{}
err := c.BindQuery(req)
if err != nil {
c.JSON(http.StatusBadRequest, err.Error())
return
}
c.Status(http.StatusOK)
})
이때 Param의 경우는 애초에 path에 있는 값이라서 값이 비어있는 경우는 다른 path로 인식하기에 사실상 binding의 필요성은 잘 모르겠고, Query의 경우는 key는 있어도 값을 주지 않으면 binding:"required"에서 걸리게 된다.
관련 코드
github.com/KimGenius/gin-gonic-validation-test
끝.
'TIL' 카테고리의 다른 글
Tistory 너무 불편해 (0) | 2020.10.27 |
---|---|
Golang 빈 Array Json으로 output 시 null(nil)이 되는 현상 (0) | 2020.09.14 |
React v16 lifecycle - Updating (0) | 2019.09.21 |
React v16 lifecycle - Mounting (0) | 2019.09.21 |
React 부모 컴포넌트의 props가 같은 값으로 set 했을 시 자식 컴포넌트에서의 rendering에 대해서 (0) | 2019.09.16 |