qtag is a small, reflection-based Go package for decoding HTTP query parameters into strongly-typed structs using struct tags.
It is designed to be minimal, dependency-free, and ergonomic.
⚠️ Warning This package is still under active development. APIs, behavior, and tag syntax may change.
- Decode
url.Valuesinto a struct using tags - Works directly with
*http.Request - Supports common Go scalar types
- Supports
encoding.TextUnmarshaler - Opt-in field decoding via tags
- Ignore fields explicitly
- Planned extensibility (e.g. additional tag options)
go get github.com/swamphacks/qtag
Add a qt tag to any struct field you want populated from the query string.
type QueryParams struct {
Limit int64 `qt:"limit"`
Page int64 `qt:"page"`
}
Given a request like:
https://example.com/some/endpoint?limit=200&page=2
You can decode it as follows:
var qp QueryParams
err := qtag.Decode(r, &qp)
if err != nil {
// handle error
}
If you already have url.Values, you can call Unmarshal directly:
values := url.Values{
"limit": {"100"},
"page": {"1"},
}
var qp QueryParams
err := qtag.Unmarshal(values, &qp)
Currently supported field types:
stringboolintint64float32float64- Any type implementing
encoding.TextUnmarshaler
If a field implements encoding.TextUnmarshaler, it will be preferred over built-in parsing.
Field string `qt:"field_name"`
Use - to explicitly ignore a field:
InternalID string `qt:"-"`
Default values are supported via default=... in the tag:
type QueryParams struct {
Limit int64 `qt:"limit,default=25"`
Page int64 `qt:"page,default=1"`
}
If the query parameter is missing or empty, the default value will be used.
Note: Default parsing follows the same rules as normal decoding and must be valid for the field type.
qtag returns descriptive errors when:
- A non-struct pointer is provided
- A value cannot be parsed into the target type
- An unsupported field type is encountered
Example:
Cannot parse limit with value abc into an integer.