golang将结构体编码为URL查询参数插件库go-querystring的使用

go-querystring 使用指南

go-querystring 是一个将 Go 结构体编码为 URL 查询参数的库。

安装

import "github.com/google/go-querystring/query"

基本用法

go-querystring 主要用于将表示 URL 查询参数的结构体转换为查询字符串。以下是一个简单示例:

package main

import (
	"fmt"
	"github.com/google/go-querystring/query"
)

// 定义查询参数结构体
type Options struct {
	Query   string `url:"q"`    // 使用url标签指定查询参数名
	ShowAll bool   `url:"all"`  // 布尔值会自动转换为字符串
	Page    int    `url:"page"` // 数字类型也会自动转换
}

func main() {
	// 创建结构体实例
	opt := Options{
		Query:   "foo",
		ShowAll: true,
		Page:    2,
	}
	
	// 将结构体编码为查询参数
	v, err := query.Values(opt)
	if err != nil {
		panic(err)
	}
	
	// 输出编码后的查询字符串
	fmt.Println(v.Encode()) // 输出: "q=foo&all=true&page=2"
}

高级用法

嵌套结构体

type Filter struct {
	Category string `url:"category"`
	PriceMin int    `url:"price_min"`
}

type SearchOptions struct {
	Query  string `url:"q"`
	Filter Filter `url:",inline"` // 使用inline标签将嵌套结构体平铺
}

func main() {
	opt := SearchOptions{
		Query: "laptop",
		Filter: Filter{
			Category: "electronics",
			PriceMin: 500,
		},
	}
	
	v, _ := query.Values(opt)
	fmt.Println(v.Encode()) // 输出: "q=laptop&category=electronics&price_min=500"
}

数组/切片参数

type Options struct {
	Colors []string `url:"color"` // 数组会自动转换为多个同名参数
}

func main() {
	opt := Options{
		Colors: []string{"red", "green", "blue"},
	}
	
	v, _ := query.Values(opt)
	fmt.Println(v.Encode()) // 输出: "color=red&color=green&color=blue"
}

忽略零值

type Options struct {
	Query string `url:"q,omitempty"` // 使用omitempty标签忽略零值
	Page  int    `url:"page,omitempty"`
}

func main() {
	opt := Options{
		Query: "",  // 空字符串
		Page:  0,   // 零值
	}
	
	v, _ := query.Values(opt)
	fmt.Println(v.Encode()) // 输出: "" (因为都是零值被忽略)
}

注意事项

  1. 结构体字段必须公开(首字母大写)才能被编码
  2. 支持基本类型(string, int, bool等)、切片/数组和嵌套结构体
  3. 使用url标签控制字段名称和编码行为
  4. 对于复杂的参数结构,可以考虑使用嵌套结构体

替代方案

如果你需要一个既能编码又能解码查询字符串的库,可以考虑以下替代方案:

  • gorilla/schema
  • pasztorpisti/qs
  • hetiansu5/urlquery
  • ggicci/httpin (仅解码)

更多关于golang将结构体编码为URL查询参数插件库go-querystring的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang将结构体编码为URL查询参数插件库go-querystring的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


go-querystring库使用指南

go-querystring是一个用于将Go结构体编码为URL查询参数的库,它提供了一种简单的方式来将结构体转换为URL查询字符串。

安装

go get github.com/google/go-querystring/query

基本用法

简单结构体转换

package main

import (
	"fmt"
	"github.com/google/go-querystring/query"
)

type Options struct {
	Query   string `url:"q"`
	ShowAll bool   `url:"all"`
	Page    int    `url:"page"`
}

func main() {
	opt := Options{
		Query:   "golang",
		ShowAll: true,
		Page:    2,
	}

	v, err := query.Values(opt)
	if err != nil {
		panic(err)
	}

	fmt.Println(v.Encode()) // 输出: q=golang&all=true&page=2
}

嵌套结构体处理

type Filter struct {
	Category string `url:"category"`
	PriceMin int    `url:"price_min"`
}

type SearchOptions struct {
	Query  string `url:"q"`
	Filter Filter `url:"filter"`
}

func main() {
	opt := SearchOptions{
		Query: "laptop",
		Filter: Filter{
			Category: "electronics",
			PriceMin: 500,
		},
	}

	v, err := query.Values(opt)
	if err != nil {
		panic(err)
	}

	fmt.Println(v.Encode()) // 输出: q=laptop&filter.category=electronics&filter.price_min=500
}

切片和数组处理

type Options struct {
	IDs     []int  `url:"id"`
	Colors  []string `url:"color"`
}

func main() {
	opt := Options{
		IDs:    []int{1, 2, 3},
		Colors: []string{"red", "green", "blue"},
	}

	v, err := query.Values(opt)
	if err != nil {
		panic(err)
	}

	fmt.Println(v.Encode()) // 输出: id=1&id=2&id=3&color=red&color=green&color=blue
}

自定义编码器

type CustomTime struct {
	time.Time
}

func (t CustomTime) EncodeValues(key string, v *url.Values) error {
	v.Set(key, t.Format("2006-01-02"))
	return nil
}

type Options struct {
	Date CustomTime `url:"date"`
}

func main() {
	opt := Options{
		Date: CustomTime{time.Now()},
	}

	v, err := query.Values(opt)
	if err != nil {
		panic(err)
	}

	fmt.Println(v.Encode()) // 输出类似: date=2023-05-15
}

忽略空值

type Options struct {
	Query string `url:"q,omitempty"`
	Page  int    `url:"page,omitempty"`
}

func main() {
	opt := Options{
		Query: "",
		Page:  0,
	}

	v, err := query.Values(opt)
	if err != nil {
		panic(err)
	}

	fmt.Println(v.Encode()) // 输出空字符串,因为所有字段都是空值且标记了omitempty
}

自定义分隔符

对于嵌套结构体,默认使用点(.)作为分隔符,但可以自定义:

type Filter struct {
	Category string `url:"category"`
}

type Options struct {
	Query  string `url:"q"`
	Filter Filter `url:"filter,comma"` // 使用逗号作为分隔符
}

func main() {
	opt := Options{
		Query: "test",
		Filter: Filter{
			Category: "books",
		},
	}

	v, err := query.Values(opt)
	if err != nil {
		panic(err)
	}

	fmt.Println(v.Encode()) // 输出: q=test&filter,category=books
}

高级特性

处理指针字段

type Options struct {
	Query *string `url:"q,omitempty"`
	Page  *int    `url:"page,omitempty"`
}

func main() {
	q := "golang"
	opt := Options{
		Query: &q,
		Page:  nil,
	}

	v, err := query.Values(opt)
	if err != nil {
		panic(err)
	}

	fmt.Println(v.Encode()) // 输出: q=golang
}

自定义标签名称

type Options struct {
	SearchTerm string `qs:"term"`
	PageNum    int    `qs:"page"`
}

// 使用自定义标签名
func main() {
	opt := Options{
		SearchTerm: "golang",
		PageNum:    2,
	}

	// 使用WithTag指定自定义标签名
	encoder := query.NewEncoder(query.WithTag("qs"))
	v, err := encoder.Encode(opt)
	if err != nil {
		panic(err)
	}

	fmt.Println(v.Encode()) // 输出: term=golang&page=2
}

实际应用示例

package main

import (
	"fmt"
	"net/url"
	"github.com/google/go-querystring/query"
)

type Pagination struct {
	Page    int `url:"page"`
	PerPage int `url:"per_page"`
}

type Filter struct {
	Category string   `url:"category,omitempty"`
	PriceMin *float64 `url:"price_min,omitempty"`
	PriceMax *float64 `url:"price_max,omitempty"`
}

type SearchRequest struct {
	Query      string     `url:"q"`
	Pagination Pagination `url:"pagination"`
	Filters    []Filter   `url:"filter"`
	Sort       string     `url:"sort,omitempty"`
}

func main() {
	minPrice := 100.0
	req := SearchRequest{
		Query: "laptop",
		Pagination: Pagination{
			Page:    1,
			PerPage: 20,
		},
		Filters: []Filter{
			{
				Category: "electronics",
				PriceMin: &minPrice,
			},
			{
				Category: "computers",
			},
		},
		Sort: "price_desc",
	}

	v, err := query.Values(req)
	if err != nil {
		panic(err)
	}

	baseURL := "https://api.example.com/products"
	fullURL := fmt.Sprintf("%s?%s", baseURL, v.Encode())
	fmt.Println(fullURL)
	// 输出类似: https://api.example.com/products?q=laptop&pagination.page=1&pagination.per_page=20&filter.0.category=electronics&filter.0.price_min=100&filter.1.category=computers&sort=price_desc
}

go-querystring库提供了一种简洁的方式来处理结构体到URL查询参数的转换,特别适合构建REST API客户端时使用。它的主要优点是支持嵌套结构体、切片、自定义编码和丰富的标签选项。

回到顶部