将URL参数转换为Go中的JSON格式,使用http.Request。

huangapple go评论94阅读模式
英文:

Converting URL Params to JSON in Go with http.Request

问题

我正在验证由请求生成的参数,但与使用 JSON 进行请求时不同,我无法轻松地将查询参数转换为其结构体对应项。使用以下代码:

type ItemsRequest struct {
	Item string `json:"item"`
}
func ValidateItemRequest(r *http.Request, w http.ResponseWriter) map[string]interface{} {
	var itemRequest ItemsRequest
	rules := govalidator.MapData{
		"item": []string{"numeric"},
	}

	opts := govalidator.Options{
		Request:         r,    
		Rules:           rules,
		Data:            &itemRequest,
		RequiredDefault: true,
	}
	v := govalidator.New(opts)
    
	e := v.Validate()
    // 访问 itemsRequest.item

}

如果我使用 e.ValidateJSON() 并通过请求体传递数据,这样可以工作。

如果我使用 e.Validate() 并通过 URL 参数传递数据,这样就不起作用。

我以为结构体中的 json 标签是问题所在,但是删除它后结果相同。我不认为 Validate() 应该填充结构体,那么我应该如何传递 URL 的值?

我知道我可以使用 r.URL.Query().Get() 手动获取每个值,但在验证了我想要的一切之后,这似乎非常冗余。

英文:

I'm validating parameters made from a request, but unlike when the request is made in JSON, I'm not able to easily convert query params into it's struct counterpart. Using the following:

https://thedevsaddam.medium.com/an-easy-way-to-validate-go-request-c15182fd11b1

type ItemsRequest struct {
	Item         string `json:"item"`
}
func ValidateItemRequest(r *http.Request, w http.ResponseWriter) map[string]interface{} {
	var itemRequest ItemsRequest
	rules := govalidator.MapData{
		"item":        []string{"numeric"},
	}

	opts := govalidator.Options{
		Request:         r,    
		Rules:           rules,
		Data:            &itemRequest ,
		RequiredDefault: true,
	}
	v := govalidator.New(opts)
    
	e := v.Validate()
    // access itemsRequest.item

}

If I use e.ValidateJSON() and pass the data in via the body, this works

If I use e.Validate() and pass the data in via url params, this doesn't work.

I assumed the json tag in the struct was the issue, but removing that yields the same result. I don't think Validate() is supposed to populate the struct, but then how am I supposed to pass in the values of the URL?

I know I can use r.URL.Query().Get() to manually pull in each value, but that seems super redundant after I just validated everything I want.

答案1

得分: 1

https://pkg.go.dev/github.com/gorilla/schema 可以为您完成繁重的工作,将 url.Values 转换为 struct,并进行一些模式验证。

它支持类似于 json 的结构字段标签,并且还可以与表单数据或多部分表单数据一起使用。

package main

import (
    "github.com/gorilla/schema"
    "net/url"
    "fmt"
)

type Person struct {
    Name  string
    Phone string
}

func main() {
    var decoder = schema.NewDecoder()
    u, err := url.Parse("http://localhost/?name=daniel&phone=612-555-4321")
    if err != nil { panic(err) }
    var person Person
    err = decoder.Decode(&person, u.Query())
    if err != nil {
        // 处理错误
    }
    fmt.Printf("%+v\n", person)
}
英文:

https://pkg.go.dev/github.com/gorilla/schema can do the heavy lifting for you, converting url.Values into a struct and doing some schema validation as well.

It supports struct field tags much like - and compatible with - json, and can also be used with eg form data or multi-part form data.

package main

import(
   "github.com/gorilla/schema"
   "net/url"
   "fmt"
)


type Person struct {
    Name  string
    Phone string
}

func main() {
    var decoder = schema.NewDecoder()
    u, err := url.Parse("http://localhost/?name=daniel&phone=612-555-4321")
    if err != nil { panic(err) }
    var person Person
    err = decoder.Decode(&person, u.Query())
    if err != nil {
        // Handle error
    }
    fmt.Printf("%+v\n", person)
}

答案2

得分: 0

首先,使用查询结果填充结构体,然后进行验证:

q := request.URL.Query()
myStruct := {
   Field1: q.Get("field1"),
   Field2: q.Get("field2"),
   ...
}
// 处理非字符串字段

// 验证结构体
英文:

First populate the struct with the values from the query, then validate it:

q:=request.URL.Query()
myStruct:= {
   Field1: q.Get("field1"),
   Field2: q.Get("field2"),
  ...
}
// Deal with non-string fields

// Validate the struct

huangapple
  • 本文由 发表于 2021年11月6日 23:11:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/69865199.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定