Hi I want to transform get query parameters into a structure in Go, for example I have this structure:
type Filter struct {
Offset int64 `json:"offset"`
Limit int64 `json:"limit"`
SortBy string `json:"sortby"`
Asc bool `json:"asc"`
//User specific filters
Username string `json:"username"`
First_Name string `json:"first_name"`
Last_Name string `json:"last_name"`
Status string `json:"status"`
}
And I have the optional parameters that the user can specify when sending a get request which are Offset
, Limit
, SortBy
, Asc
, Username
, First_Name
, Last_Name
, Status
.
If those parameters were sent in the body then I would do this:
b, err := ioutil.ReadAll(r.Body)
if err != nil {
log.WithFields(logFields).Errorf("Reading Body Message:failed:%v", err)
return
}
var filter Filter
err = json.Unmarshal(b, &filter)
But I can't send body in a GET
request so what is the solution instead of getting each parameter alone and then putting them into a structure?
Using gorilla's
schema
packageThe
github.com/gorilla/schema
package was invented exactly for this.You can use struct tags to tell how to map URL parameters to struct fields, the
schema
package looks for the"schema"
tag keys.Using it:
Marshaling and unmarshaling using
json
Note that the
schema
package will also try to convert parameter values to the type of the field.If the struct would only contain fields of
[]string
type (or you're willing to make that compromise), you can do that without theschema
package.Request.Form
is amap
, mapping fromstring
to[]string
(as one parameter may be listed multiple times in the URL:And
url.Values
:So for example if your
Filter
struct would look like this:You could simply use the
json
package to marshalr.Form
, then unmarshal it into your struct:This solution handles if multiple values are provided for the same parameter name. If you don't care about multiple values and you just want one, you first have to "transform"
r.Form
to amap
with singlestring
values instead of[]string
.This is how it could look like:
And then you can marshal
m
and unmarshal into it into theFilter
struct the same way.