Validation go中验证http请求的惯用方法
我需要验证我的http请求是否有两个参数,Start和End。目前,我设置了一个默认值,该值不应显示为任何一个参数,并与其他无效值一起检查。然而,这感觉像是一个黑客。正确的方法应该是什么 这是我的密码:Validation go中验证http请求的惯用方法,validation,http,go,Validation,Http,Go,我需要验证我的http请求是否有两个参数,Start和End。目前,我设置了一个默认值,该值不应显示为任何一个参数,并与其他无效值一起检查。然而,这感觉像是一个黑客。正确的方法应该是什么 这是我的密码: type Request struct { Start int `json: "start"` End int `json: "end"` } func HandlePost(w http.ResponseWriter, r *http.Request) { body
type Request struct {
Start int `json: "start"`
End int `json: "end"`
}
func HandlePost(w http.ResponseWriter, r *http.Request) {
body , _ := ioutil.ReadAll(r.Body)
reqData := Request{Start: -1, End: -1} // < whats the correct way to do this
json.Unmarshal(body, &reqData)
if reqData.Start < 0 && reqData.End < 0 {
w.WriteHeader(http.StatusBadRequest)
return
}
// rest of the logic
}
类型请求结构{
Start int`json:“Start”`
End int`json:“End”`
}
func HandlePost(w http.ResponseWriter,r*http.Request){
body,Util:=ioutil.ReadAll(r.body)
reqData:=请求{开始:-1,结束:-1}/<正确的方法是什么
Unmarshal(body和reqData)
如果reqData.Start<0&&reqData.End<0{
w、 WriteHeader(http.StatusBadRequest)
返回
}
//其余的逻辑
}
您可以使用getInt。
如果json缺少所需的键,则会出现错误
我建议使用基准测试,而不是由代码美或任何其他预感决定,您可以使用这些预感作为验证请求的基本方法。但如果您想要更复杂的东西,您需要编写自己的自定义验证器函数。e、 g
type Request struct {
Start int `json: "start"`
End int `json: "end"`
}
func (a *Request) validate() url.Values {
err := url.Values{}
// Write your own validation rules
if a.Start < 0 {
err.Add("Start", "Start cannot be less than 0");
}
return err;
}
func handler(w http.ResponseWriter, r *http.Request) {
requestBody := &Request{}
defer r.Body.Close()
if err := json.NewDecoder(r.Body).Decode(requestBody); err != nil {
panic(err)
}
if errors := requestBody.validate(); len(errors) > 0 {
err := map[string]interface{}{"validationError": errors}
w.Header().Set("Content-type", "application/json")
w.WriteHeader(http.StatusBadRequest)
json.NewEncoder(w).Encode(err)
}
fmt.Fprint(w, "success request scenario!")
}
类型请求结构{
Start int`json:“Start”`
End int`json:“End”`
}
func(a*请求)validate()url.Values{
错误:=url.Values{}
//编写自己的验证规则
如果a.开始<0{
错误添加(“开始”,“开始不能小于0”);
}
返回错误;
}
func处理程序(w http.ResponseWriter,r*http.Request){
requestBody:=&请求{}
延迟r.Body.Close()
如果err:=json.NewDecoder(r.Body).Decode(requestBody);err!=nil{
恐慌(错误)
}
如果错误:=requestBody.validate();len(错误)>0{
err:=map[string]接口{}{“validationError”:errors}
w、 Header().Set(“内容类型”、“应用程序/json”)
w、 WriteHeader(http.StatusBadRequest)
json.NewEncoder(w).Encode(err)
}
Fprint(w,“成功请求场景!”)
}
下面是使用结构标记和指针验证结构的另一种方法。请注意,如果0是要传递的有效对象,则此解决方案将不起作用。
omitempty认为0值为空。如果您想让它工作,将考虑0是有效的,请删除指针并修改IsValid方法
package main
import (
"encoding/json"
"fmt"
)
type Request struct {
Start *int `json: "start,omitempty"`
End *int `json: "end,omitempty"`
}
func (r Request) IsValid() (bool, error) {
if r.Start == nil {
return false, fmt.Errorf("start is missing")
}
if r.End == nil {
return false, fmt.Errorf("end is missing")
}
return true, nil
}
var (
invalidStartb = `{"end": 1}`
invalidEndb = `{"start": 1}`
valid = `{"start": 1, "end": 1}`
)
func main() {
var r Request
_ = json.Unmarshal([]byte(invalidStartb), &r)
fmt.Println(r.IsValid())
r = Request{}
_ = json.Unmarshal([]byte(invalidEndb), &r)
fmt.Println(r.IsValid())
r = Request{}
_ = json.Unmarshal([]byte(valid), &r)
fmt.Println(r.IsValid())
}
这里的可运行版本通常你会使用指针:如果请求中没有传递任何值,那么字段将保持为
nil
。可能重复感谢,@mkopriva和zaky得到了我想要的答案。其他答案使用的外部库可能不那么惯用。你们中的任何一个能回答吗?我将把它标记为已接受的答案?请注意,这个问题实际上与HTTP无关。正如@mkopriva提到的,惯用的方法是使用指针,而不是使用库。通过使用指针,当未指定时,该值将为nil
,而不是设置为0。当您希望在未提供值的情况下设置默认值时,指针可能是惯用的方法。当您想要验证时,可能是错误的方式。假设您有一个很大的属性列表,通过使用指针,您可以解组整个结构,只是为了发现它无效。假设您有几个字段需要验证,在这种情况下,您可以先检查可能丢失的最有可能的字段,然后快速返回。糟糕的是,我一开始就误解了这个问题,使用验证器库更好。很抱歉:p@Ullaakut然后再把你的票否决:)当然,如果是你的话。非常感谢。