qstring

package module
v0.0.0-...-5a99d46 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 4, 2020 License: MIT Imports: 8 Imported by: 2

README

qstring

This package provides an easy way to marshal and unmarshal url query string data to and from structs.

Installation

$ go get github.com/dyninc/qstring

Examples

Unmarshaling
package main

import (
	"net/http"

	"github.com/dyninc/qstring"
)

// Query is the http request query struct.
type Query struct {
	Names    []string
	Limit     int
	Page      int
}

func handler(w http.ResponseWriter, req *http.Request) {
	query := &Query{}
	err := qstring.Unmarshal(req.Url.Query(), query)
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
	}

	// ... run conditional logic based on provided query parameters
}

The above example will unmarshal the query string from an http.Request and unmarshal it into the provided struct. This means that a query of ?names=foo&names=bar&limit=50&page=1 would be unmarshaled into a struct similar to the following:

Query{
	Names: []string{"foo", "bar"},
	Limit: 50,
	Page: 1,
}
Marshalling

qstring also exposes two methods of Marshaling structs into Query parameters, one will Marshal the provided struct into a raw query string, the other will Marshal a struct into a url.Values type. Some Examples of both follow.

Marshal Raw Query String
package main

import (
	"fmt"
	"net/http"

	"github.com/dyninc/qstring"
)

// Query is the http request query struct.
type Query struct {
	Names    []string
	Limit     int
	Page      int
}

func main() {
	query := &Query{
		Names: []string{"foo", "bar"},
		Limit: 50,
		Page: 1,
	}
	q, err := qstring.MarshalString(query)
	fmt.Println(q)
	// Output: names=foo&names=bar&limit=50&page=1
}
Marshal url.Values
package main

import (
	"fmt"
	"net/http"

	"github.com/dyninc/qstring"
)

// Query is the http request query struct.
type Query struct {
	Names    []string
	Limit     int
	Page      int
}

func main() {
	query := &Query{
		Names: []string{"foo", "bar"},
		Limit: 50,
		Page: 1,
	}
	q, err := qstring.Marshal(query)
	fmt.Println(q)
	// Output: map[names:[foo, bar] limit:[50] page:[1]]
}
Nested

In the same spirit as other Unmarshaling libraries, qstring allows you to Marshal/Unmarshal nested structs

package main

import (
	"net/http"

	"github.com/dyninc/qstring"
)

// PagingParams represents common pagination information for query strings
type PagingParams struct {
	Page int
	Limit int
}

// Query is the http request query struct.
type Query struct {
	Names    []string
	PageInfo PagingParams
}
Complex Structures

Again, in the spirit of other Unmarshaling libraries, qstring allows for some more complex types, such as pointers and time.Time fields. A more complete example might look something like the following code snippet

package main

import (
	"time"
)

// PagingParams represents common pagination information for query strings
type PagingParams struct {
	Page int	`qstring:"page"`
	Limit int `qstring:"limit"`
}

// Query is the http request query struct.
type Query struct {
	Names    []string
	IDs      []int
	PageInfo *PagingParams
	Created  time.Time
	Modified time.Time
}

Additional Notes

  • All Timestamps are assumed to be in RFC3339 format
  • A struct field tag of qstring is supported and supports all of the features you've come to know and love from Go (un)marshalers.
    • A field tag with a value of qstring:"-" instructs qstring to ignore the field.
    • A field tag with an the omitempty option set will be ignored if the field being marshaled has a zero value. qstring:"name,omitempty"
Custom Fields

In order to facilitate more complex queries qstring also provides some custom fields to save you a bit of headache with custom marshal/unmarshaling logic. Currently the following custom fields are provided:

  • qstring.ComparativeTime - Supports timestamp query parameters with optional logical operators (<, >, <=, >=) such as ?created<=2006-01-02T15:04:05Z

Benchmarks

BenchmarkUnmarshall-4 	  500000	      2711 ns/op	     448 B/op	      23 allocs/op
BenchmarkRawPLiteral-4	 1000000	      1675 ns/op	     448 B/op	      23 allocs/op
ok  	github.com/dyninc/qstring	3.163s

Documentation

Overview

Package qstring provides an an easy way to marshal and unmarshal query string data to and from structs representations.

This library was designed with consistency in mind, to this end the provided Marshal and Unmarshal interfaces should seem familiar to those who have used packages such as "encoding/json".

Additionally this library includes support for converting query parameters to and from time.Time types as well as nested structs and pointer values.

Index

Examples

Constants

View Source
const (
	// Tag indicates the name of the struct tag to extract from provided structs
	// when marshalling or unmarshalling
	Tag = "qstring"
)

Variables

This section is empty.

Functions

func Marshal

func Marshal(v interface{}) (url.Values, error)

Marshal marshals the provided struct into a url.Values collection

func MarshalString

func MarshalString(v interface{}) (string, error)

Marshal marshals the provided struct into a raw query string and returns a conditional error

Example
// Query is the http request query struct.
type Query struct {
	Names []string
	Limit int
	Page  int
}

query := &Query{
	Names: []string{"foo", "bar"},
	Limit: 50,
	Page:  1,
}
q, _ := MarshalString(query)
os.Stdout.Write([]byte(q))
Output:

limit=50&names=foo&names=bar&page=1

func Unmarshal

func Unmarshal(data url.Values, v interface{}) error

Unmarshal unmarshalls the provided url.Values (query string) into the interface provided

Example
// Query is the http request query struct.
type Query struct {
	Names []string
	Limit int
	Page  int
}

query := &Query{}
qValues, _ := url.ParseQuery("names=foo&names=bar&limit=50&page=1")
err := Unmarshal(qValues, query)
if err != nil {
	panic("Unable to Parse Query String")
}

os.Stdout.Write([]byte(fmt.Sprintf("%+v", query)))
Output:

&{Names:[foo bar] Limit:50 Page:1}
Example (Complex)
// PagingParams represents common pagination information for query strings
type PagingParams struct {
	Page  int `qstring:"page"`
	Limit int `qstring:"limit"`
}

// Query is the http request query struct.
type Query struct {
	Names    []string
	IDs      []int
	PageInfo *PagingParams
	Created  time.Time
}
query := &Query{}
qValues, _ := url.ParseQuery("names=foo&names=bar&limit=50&page=1&ids=1&ids=2&created=2006-01-02T15:04:05Z")
err := Unmarshal(qValues, query)
if err != nil {
	panic("Unable to Parse Query String")
}
Output:

Types

type ComparativeString

type ComparativeString struct {
	Operator string
	Str      string
}

func (*ComparativeString) Parse

func (c *ComparativeString) Parse(query string) error

Parse is used to parse a query string into a ComparativeString instance

func (ComparativeString) String

func (c ComparativeString) String() string

String returns this ComparativeString instance in the form of the query parameter that it came in on

type ComparativeTime

type ComparativeTime struct {
	Operator string
	Time     time.Time
}

ComparativeTime is a field that can be used for specifying a query parameter which includes a conditional operator and a timestamp

Example
type DateQuery struct {
	Created  ComparativeTime
	Modified ComparativeTime
}

var query DateQuery
qValues, _ := url.ParseQuery("created=>=2006-01-02T15:04:05Z&modified=<=2016-01-01T15:04Z")
err := Unmarshal(qValues, &query)
if err != nil {
	panic("Unable to Parse Query String")
}
Output:

func NewComparativeTime

func NewComparativeTime() *ComparativeTime

NewComparativeTime returns a new ComparativeTime instance with a default operator of "="

func (*ComparativeTime) Parse

func (c *ComparativeTime) Parse(query string) error

Parse is used to parse a query string into a ComparativeTime instance

func (ComparativeTime) String

func (c ComparativeTime) String() string

String returns this ComparativeTime instance in the form of the query parameter that it came in on

type InvalidMarshalError

type InvalidMarshalError struct {
	Type reflect.Type
}

An InvalidMarshalError describes an invalid argument passed to Marshal or MarshalValue. (The argument to Marshal must be a non-nil pointer.)

func (InvalidMarshalError) Error

func (e InvalidMarshalError) Error() string

type InvalidUnmarshalError

type InvalidUnmarshalError struct {
	Type reflect.Type
}

An InvalidUnmarshalError describes an invalid argument passed to Unmarshal. (The argument to Unmarshal must be a non-nil pointer.)

func (InvalidUnmarshalError) Error

func (e InvalidUnmarshalError) Error() string

type Marshaller

type Marshaller interface {
	MarshalQuery() (url.Values, error)
}

Marshaller defines the interface for performing custom marshalling of struct values into query strings

type Unmarshaller

type Unmarshaller interface {
	UnmarshalQuery(url.Values) error
}

Unmarshaller defines the interface for performing custom unmarshalling of query strings into struct values

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL