• Stars
    star
    19
  • Rank 1,123,781 (Top 23 %)
  • Language
    Go
  • License
    MIT License
  • Created almost 6 years ago
  • Updated over 3 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Go package to easily convert a URL's query parameters/values into usable struct values of the correct types.

Query Param

Build Status codecov Go Report Card Documentation Mentioned in Awesome Go

Stop accessing query strings and repeatedly parsing them into your preferred values - queryparam can do that for you!

Installation

go get -u github.com/tomwright/queryparam

Usage

Please use the latest major version. This requires the /v4 at the end of the import as per the go mod documentation.

import github.com/tomwright/queryparam/v4

Examples

For examples see godoc examples.

Quickstart

Transform your http handlers from this...

func searchUsersHandler(r *http.Request, rw http.ResponseWriter) {
	values := r.URL.Query()

	userIDs := make([]string, 0)
	if userIDsStr := values.Get("id"); userIDsStr != "" {
		userIDs = strings.Split(userIDsStr, ",")
	}
	teamIDs := make([]string, 0)
	if teamIDsStr := values.Get("team-id"); teamIDsStr != "" {
		teamIDs = strings.Split(teamIDsStr, ",")
	}
	mustBeActive := false
	switch strings.ToLower(values.Get("must-be-active")) {
	case "true", "yes", "y":
		mustBeActive = true
	case "":
		break
	default:
		// unhandled bool value... handle as 400 or ignore to default as false
	}
	createdAfter := time.Time{}
	if createdAfterStr := values.Get("must-be-active"); createdAfterStr != "" {
		var err error
		createdAfter, err = time.Parse(time.RFC3339, createdAfterStr)
		if err != nil {
			// bad time value
		}
	}

	users, err := searchUsers(userIDs, teamIDs, mustBeActive, createdAfter)

	// handle users and err...
}

To this...

func searchUsersHandler(r *http.Request, rw http.ResponseWriter) {
	req := struct {
		UserIDs      []string  `queryparam:"id"`
		TeamIDs      []string  `queryparam:"team-id"`
		MustBeActive bool      `queryparam:"must-be-active"`
		CreatedAfter time.Time `queryparam:"created-after"`
	}{}

	err := queryparam.Parse(r.URL.Query(), &req)
	switch err {
	case nil:
		break
	case queryparam.ErrInvalidBoolValue: // only necessary if the request contains a bool value
		// they have entered a non-bool value.
		// this can be handled this as a 400 or ignored to default to false.
		return
	default:
		// something went wrong when parsing a value.
		// send a 500.
		return
	}

	users, err := searchUsers(req.UserIDs, req.TeamIDs, req.MustBeActive, req.CreatedAfter)

	// handle users and err...
}

Types

By default queryparam can parse the following types.

  • string
  • []string
  • int
  • int32
  • int64
  • float32
  • float64
  • bool
  • time.Time
  • queryparam.Present

Custom Types

You can add custom type parsers and setters with the following:

// your custom type.
type MyCustomStringType string

// add a value parser for the custom type.
queryparam.DefaultParser.ValueParsers[reflect.TypeOf(MyCustomStringType(""))] = func(value string, _ string) (reflect.Value, error) {
    return reflect.ValueOf(MyCustomStringType(value)), nil
}

You can override the default value parsers in a similar manner...

queryparam.DefaultParser.ValueParsers[reflect.TypeOf("")] = func(value string, _ string) (reflect.Value, error) {
    // my custom string parser
    return reflect.ValueOf(value), nil
}