Home > Software design >  Converting URL Params to JSON in Go with http.Request
Converting URL Params to JSON in Go with http.Request

Time:11-07

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.

CodePudding user response:

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

CodePudding user response:

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
  • Related