qs
The qs
package can marshal and unmarshal structs into/from url query strings.
The interface of qs
is very similar to that of some standard marshaler
packages like encoding/json
, encoding/xml
.
Note that html forms are often POST
-ed in the HTTP request body in the same
format as query strings (with an encoding called application/x-www-form-urlencoded
)
so this package can be used for that as well.
Quick Intro
The go standard library can convert only between the (query) string and the
standard url.Values
data type
(which is a map[string][]string
).
This qs
package adds struct marshaling and unmarshaling to your arsenal:
+--------------+
+---------------->| query string +------------------+
| +---------+----+ |
| ^ | |
| url.Values.Encode | | url.ParseQuery |
| | v |
| +----+---------+ |
| | url.Values | |
| +---------+----+ |
| ^ | |
| qs.MarshalValues | | qs.UnmarshalValues |
| | v |
| +----+---------+ |
+-----------------+ struct |<-----------------+
qs.Marshal +--------------+ qs.Unmarshal
Example:
package main
import "fmt"
import "github.com/pasztorpisti/qs"
type Query struct {
Search string
Page int
PageSize int
Categories []string `qs:"category"`
}
func main() {
queryStr, err := qs.Marshal(&Query{
Search: "my search",
Page: 2,
PageSize: 50,
Categories: []string{"c1", "c2"},
})
fmt.Println("Marshal-Result:", queryStr, err)
var q Query
err = qs.Unmarshal(&q, queryStr)
fmt.Println("Unmarshal-Result:", q, err)
}
Features
- Support for primitive types (
bool
, int
, etc...), pointers, slices, arrays,
maps, structs, time.Time
and url.URL
. - A custom type can implement the
MarshalQS
and/or UnmarshalQS
interfaces
to handle its own marshaling/unmarshaling. - The marshaler and unmarshaler are modular and
can be extended to support new types.
This makes it possible to do several tricks. One of them is being able to
override existing type marshalers (e.g.: the
[]byte
array marshaler). - It can tell whether a type is marshallable before actually marshaling an
object of that type. Most marshalers (including the standard
encoding/json
)
can't do this! E.g.: If you have an empty slice that has a non-marshallable
item type (e.g.: function) then encoding/json
and many other marshalers
happily marshal it as an empty slice - they return with an error only if the
given slice has at least one item and they realise that it can't be marshaled. - You can create custom marshaler objects that define different defaults for
the marshaling process:
- A struct-to-query_string name transformer func that is used when the struct
field tag doesn't set a custom name for the field. The default function
converts CamelCase go struct field names to snake_case which is the standard
in case of query strings.
- When a struct field tag specifies none of the
keepempty
and omitempty
options the marshaler uses keepempty
by default. By creating a custom
marshaler you can
change the default to omitempty
. - When a struct field tag doesn't specify any of the
opt
, nil
, req
options the unmarshaler uses opt
by default. By creating a custom
unmarshaler you can change this default.
- A struct field tag can be used to:
- Exclude a field from marshaling/unmarshaling by specifying
-
as the
field name (qs:"-"
). - Set custom name for the field in the marshaled query string.
- Set one of the
keepempty
, omitempty
options for marshaling. - Set one of the
opt
, nil
, req
options for unmarshaling.
Detailed Documentation
The godoc of the qs package
contains more detailed documentation with working examples.