Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/sonh/qs
Go module for encoding structs into URL query parameters
https://github.com/sonh/qs
encoder encoding form form-data go query-parameters querystring url-parameters
Last synced: 14 days ago
JSON representation
Go module for encoding structs into URL query parameters
- Host: GitHub
- URL: https://github.com/sonh/qs
- Owner: sonh
- License: mit
- Created: 2020-10-02T09:50:35.000Z (about 4 years ago)
- Default Branch: main
- Last Pushed: 2024-03-05T06:22:38.000Z (8 months ago)
- Last Synced: 2024-07-31T20:51:37.276Z (3 months ago)
- Topics: encoder, encoding, form, form-data, go, query-parameters, querystring, url-parameters
- Language: Go
- Homepage:
- Size: 39.1 KB
- Stars: 75
- Watchers: 3
- Forks: 5
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
- awesome-go - qs - Go module for encoding structs into URL query parameters. (Forms / Search and Analytic Databases)
- awesome-go-extra - qs - 10-02T09:50:35Z|2022-03-01T18:15:08Z| (Forms / Advanced Console UIs)
README
# qs #
[![Build](https://github.com/sonh/qs/actions/workflows/go.yml/badge.svg?branch=main)](https://github.com/sonh/qs/actions)
[![Codecov](https://codecov.io/gh/sonh/qs/branch/main/graph/badge.svg)](https://codecov.io/gh/sonh/qs)
[![GoReportCard](https://goreportcard.com/badge/github.com/sonh/qs)](https://goreportcard.com/report/github.com/sonh/qs)
[![Release](https://img.shields.io/github/release/sonh/qs.svg?color=brightgreen)](https://github.com/sonh/qs/releases/)
[![PkgGoDev](https://pkg.go.dev/badge/github.com/sonh/qs)](https://pkg.go.dev/github.com/sonh/qs)
[![MIT License](https://img.shields.io/badge/License-MIT-blue.svg)](https://github.com/sonh/qs/blob/main/LICENSE)Package sonh/qs encodes structs into url.Values.
## Installation
```bash
go get github.com/sonh/qs
```## Usage
```go
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`)
```go
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
```go
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
```go
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.
```go
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.
```go
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.
```go
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.
```go
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.
```go
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.
```go
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.