使用 http Mux 请求正文验证
Request body validation with http Mux
我正在尝试使用 Go 和 Mux 构建一个 API。我正在尝试验证传入的请求。我尝试在 Struct 上使用标签并使用 Go Validator.
验证它
这是我的结构
type Address struct {
Street string `validate:"required"`
City string `validate:"required"`
Phone string `validate:"required"`
}
我的问题是
- 有一个
POST
端点,所有字段都将通过该端点并且验证不会失败。然而,还有另一个 PATCH
端点,其中并非 Address
结构的所有字段都将被传递,因此验证失败。
例如。 API 可能收到
{
"Street": "Dummy"
}
在这种情况下验证 POST
和 PATCH
请求的最佳方法是什么。
更改我的答案
我已经对你的情况进行了测试并找到了解决方案,你必须使用 struct level validation。这是我在你的案例中的功能:
func PostRequestValidation(sl validator.StructLevel) {
address := sl.Current().Interface().(Address)
jsonMarshal, _ := json.Marshal(address)
var m map[string]interface{}
_ = json.Unmarshal(jsonMarshal, &m)
for key, val := range m {
if len(fmt.Sprintf("%s", val)) == 0 {
sl.ReportError(val, key, key, "post", "")
}
}
}
func PutRequestValidation(sl validator.StructLevel) {
address := sl.Current().Interface().(Address)
isValid := false
jsonMarshal, _ := json.Marshal(address)
var m map[string]interface{}
_ = json.Unmarshal(jsonMarshal, &m)
for _, val := range m {
if len(fmt.Sprintf("%s", val)) > 0 {
isValid = true
}
}
if !isValid {
sl.ReportError(address, "address", "Adress", "put", "")
}
}
您只需在每个验证请求上注册
// ON POST REQUEST
validate = validator.New()
validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
if name == "-" {
return ""
}
return name
})
validate.RegisterStructValidation(PostRequestValidation, Address{})
// ON PUT REQUEST
validate = validator.New()
validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
if name == "-" {
return ""
}
return name
})
validate.RegisterStructValidation(PutRequestValidation, Address{})
您可以从我的 source code 复制以获得更详细的源代码。
在 PATCH 端点中使用具有不同(如果有)验证标签的不同类型。之后转换为地址:
// Same underlying type as Address, but no validation tags
var x struct {
Street string
City string
Phone string
}
// Decode request into x, then:
addr := Address(x)
找到这个图书馆 - govalidator。这允许根据要求为每个请求创建规则。对于 POST 请求,创建一组所有字段均为必填字段的规则。对于 PATCH 请求,创建所有字段为可选的规则。
我正在尝试使用 Go 和 Mux 构建一个 API。我正在尝试验证传入的请求。我尝试在 Struct 上使用标签并使用 Go Validator.
验证它这是我的结构
type Address struct {
Street string `validate:"required"`
City string `validate:"required"`
Phone string `validate:"required"`
}
我的问题是
- 有一个
POST
端点,所有字段都将通过该端点并且验证不会失败。然而,还有另一个PATCH
端点,其中并非Address
结构的所有字段都将被传递,因此验证失败。
例如。 API 可能收到
{
"Street": "Dummy"
}
在这种情况下验证 POST
和 PATCH
请求的最佳方法是什么。
更改我的答案
我已经对你的情况进行了测试并找到了解决方案,你必须使用 struct level validation。这是我在你的案例中的功能:
func PostRequestValidation(sl validator.StructLevel) {
address := sl.Current().Interface().(Address)
jsonMarshal, _ := json.Marshal(address)
var m map[string]interface{}
_ = json.Unmarshal(jsonMarshal, &m)
for key, val := range m {
if len(fmt.Sprintf("%s", val)) == 0 {
sl.ReportError(val, key, key, "post", "")
}
}
}
func PutRequestValidation(sl validator.StructLevel) {
address := sl.Current().Interface().(Address)
isValid := false
jsonMarshal, _ := json.Marshal(address)
var m map[string]interface{}
_ = json.Unmarshal(jsonMarshal, &m)
for _, val := range m {
if len(fmt.Sprintf("%s", val)) > 0 {
isValid = true
}
}
if !isValid {
sl.ReportError(address, "address", "Adress", "put", "")
}
}
您只需在每个验证请求上注册
// ON POST REQUEST
validate = validator.New()
validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
if name == "-" {
return ""
}
return name
})
validate.RegisterStructValidation(PostRequestValidation, Address{})
// ON PUT REQUEST
validate = validator.New()
validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
if name == "-" {
return ""
}
return name
})
validate.RegisterStructValidation(PutRequestValidation, Address{})
您可以从我的 source code 复制以获得更详细的源代码。
在 PATCH 端点中使用具有不同(如果有)验证标签的不同类型。之后转换为地址:
// Same underlying type as Address, but no validation tags
var x struct {
Street string
City string
Phone string
}
// Decode request into x, then:
addr := Address(x)
找到这个图书馆 - govalidator。这允许根据要求为每个请求创建规则。对于 POST 请求,创建一组所有字段均为必填字段的规则。对于 PATCH 请求,创建所有字段为可选的规则。