qs alternatives and similar packages
Based on the "Forms" category.
Alternatively, view qs alternatives based on common mentions on social networks and blogs.
-
gorilla/csrf
DISCONTINUED. gorilla/csrf provides Cross Site Request Forgery (CSRF) prevention middleware for Go web applications & services 🔒 -
form
:steam_locomotive: Decodes url.Values into Go value(s) and Encodes Go value(s) into url.Values. Dual Array and Full map support. -
httpin
🍡 HTTP Input for Go - HTTP Request from/to Go Struct (Bi-directional Data Binding between Go Struct and http.Request) -
checker
Effortless input validation in Go with the power of struct tags. No dependencies, just pure simplicity. ✨ See how! 👀 -
queryparam
Go package to easily convert a URL's query parameters/values into usable struct values of the correct types. -
gbind
Bind data to any Go value. Can use built-in and custom expression binding capabilities; supports data validation logic for Go values. // 将数据绑定到任何 Go 值。可使用内置和自定义表达式绑定能力;支持对Go值的数据校验逻辑.
CodeRabbit: AI Code Reviews for Developers

Do you think we are missing an alternative of qs or a related project?
Popular Comparisons
README
qs
Package sonh/qs encodes structs into url.Values.
Installation
go get github.com/sonh/qs
Usage
import (
"github.com/sonh/qs"
)
Package qs exports NewEncoder()
function to create an encoder.
Encoder caches struct info to speed up encoding process, use a single instance is highly recommended.
Use WithTagAlias()
func to register custom tag alias (default is qs
)
encoder = qs.NewEncoder(
qs.WithTagAlias("myTag"),
)
Encoder has Values()
and Encode()
functions to encode structs into url.Values
.
Supported data types:
- all basic types (
bool
,uint
,string
,float64
,...) struct
slice
,array
pointer
time.Time
- custom type
Example
type Query struct {
Tags []string `qs:"tags"`
Limit int `qs:"limit"`
From time.Time `qs:"from"`
Active bool `qs:"active,omitempty"` //omit empty value
Ignore float64 `qs:"-"` //ignore
}
query := &Query{
Tags: []string{"docker", "golang", "reactjs"},
Limit: 24,
From: time.Unix(1580601600, 0).UTC(),
Ignore: 0,
}
encoder := qs.NewEncoder()
values, err := encoder.Values(query)
if err != nil {
// Handle error
}
fmt.Println(values.Encode()) //(unescaped) output: "from=2020-02-02T00:00:00Z&limit=24&tags=docker&tags=golang&tags=reactjs"
Bool format
Use int
option to encode bool to integer
type Query struct {
DefaultFmt bool `qs:"default_fmt"`
IntFmt bool `qs:"int_fmt,int"`
}
query := &Query{
DefaultFmt: true,
IntFmt: true,
}
values, _ := encoder.Values(query)
fmt.Println(values.Encode()) // (unescaped) output: "default_fmt=true&int_fmt=1"
Time format
By default, package encodes time.Time values as RFC3339 format.
Including the "second"
or "millis"
option to signal that the field should be encoded as second or millisecond.
type Query struct {
Default time.Time `qs:"default_fmt"`
Second time.Time `qs:"second_fmt,second"` //use `second` option
Millis time.Time `qs:"millis_fmt,millis"` //use `millis` option
}
t := time.Unix(1580601600, 0).UTC()
query := &Query{
Default: t,
Second: t,
Millis: t,
}
encoder := qs.NewEncoder()
values, _ := encoder.Values(query)
fmt.Println(values.Encode()) // (unescaped) output: "default_fmt=2020-02-02T00:00:00Z&millis_fmt=1580601600000&second_fmt=1580601600"
Slice/Array Format
Slice and Array default to encoding into multiple URL values of the same value name.
type Query struct {
Tags []string `qs:"tags"`
}
values, _ := encoder.Values(&Query{Tags: []string{"foo","bar"}})
fmt.Println(values.Encode()) //(unescaped) output: "tags=foo&tags=bar"
Including the comma
option to signal that the field should be encoded as a single comma-delimited value.
type Query struct {
Tags []string `qs:"tags,comma"`
}
values, _ := encoder.Values(&Query{Tags: []string{"foo","bar"}})
fmt.Println(values.Encode()) //(unescaped) output: "tags=foo,bar"
Including the bracket
option to signal that the multiple URL values should have "[]" appended to the value name.
type Query struct {
Tags []string `qs:"tags,bracket"`
}
values, _ := encoder.Values(&Query{Tags: []string{"foo","bar"}})
fmt.Println(values.Encode()) //(unescaped) output: "tags[]=foo&tags[]=bar"
The index
option will append an index number with brackets to value name.
type Query struct {
Tags []string `qs:"tags,index"`
}
values, _ := encoder.Values(&Query{Tags: []string{"foo","bar"}})
fmt.Println(values.Encode()) //(unescaped) output: "tags[0]=foo&tags[1]=bar"
Nested structs
All nested structs are encoded including the parent value name with brackets for scoping.
type User struct {
Verified bool `qs:"verified"`
From time.Time `qs:"from,millis"`
}
type Query struct {
User User `qs:"user"`
}
query := Query{
User: User{
Verified: true,
From: time.Now(),
},
}
values, _ := encoder.Values(query)
fmt.Println(values.Encode()) //(unescaped) output: "user[from]=1601623397728&user[verified]=true"
Custom Type
Implement funcs:
EncodeParam
to encode itself into query param.IsZero
to check whether an object is zero to determine whether it should be omitted when encoding. ```go type NullableName struct { First string Last string }
func (n NullableName) EncodeParam() (string, error) { return n.First + n.Last, nil }
func (n NullableName) IsZero() bool { return n.First == "" && n.Last == "" }
type Struct struct {
User NullableName qs:"user"
Admin NullableName qs:"admin,omitempty"
}
s := Struct{ User: NullableName{ First: "son", Last: "huynh", }, } encoder := qs.NewEncoder()
values, err := encoder.Values(&s) if err != nil { // Handle error fmt.Println("failed") return } fmt.Println(values.Encode()) //(unescaped) output: "user=sonhuynh"
### Limitation
- if elements in `slice/array` are `struct` data type, multi-level nesting are limited
- no decoder yet
_Will improve in future versions_
## License
Distributed under MIT License, please see license file in code for more details.
*Note that all licence references and agreements mentioned in the qs README section above
are relevant to that project's source code only.