使用 http Mux 请求正文验证

问题描述 投票:0回答:3

我正在尝试使用 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
请求的最佳方法是什么。

go mux
3个回答
2
投票

在 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)

2
投票

更改我的答案

我已经对您的案例进行了测试并找到了解决方案,您必须使用结构级别验证。这是我对您的案例的作用:

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{})

您可以复制我的源代码以获取更详细的源代码。


0
投票

找到了这个库 - govalidator。这允许根据要求为每个请求创建规则。对于 POST 请求,创建一组规则,其中所有字段均为必填。对于 PATCH 请求,创建所有字段均为可选的规则。

© www.soinside.com 2019 - 2024. All rights reserved.