Skip to main content

query

query is a directive executor who decodes/encodes a field from/to URL querystring parameters, i.e. http.Request.URL.Query().

Signature

Name: "query"
Args: KEY1 [,KEY2 [,KEY3, ...]]

Decoding

query will examine values of the keys one by one (KEY1 -> KEY2 -> ...) from the URL querystring, the first non-empty value will be used to set the corresponding field of the input struct.

Usage

type ListUsersInput struct {
IsMember bool `in:"query=is_member"`
AgeRange []int `in:"query=age_range[],age_range"`
}
Request (URL query)ListUsersInput
GET /users?is_member=1&age_range[]=3&age_range[]=5
{
IsMember: true,
AgeRange: []int{3, 5},
}
GET /users?age_range=3&age_range=5
{
IsMember: false,
AgeRange: []int{3, 5},
}
GET /users?is_member=true
{
IsMember: true,
AgeRange: []int{},
}

Runable Example

package main

import (
"fmt"
"net/http"
"net/http/httptest"

"github.com/ggicci/httpin"
"github.com/go-chi/chi/v5"
)

type ListUsersInput struct {
IsMember bool `in:"query=is_member"`
AgeRange []int `in:"query=age_range[],age_range"`
}

func ListUsers(rw http.ResponseWriter, r *http.Request) {
input := r.Context().Value(httpin.Input).(*ListUsersInput)
fmt.Printf("input: %#v\n", input)
}

func main() {
router := chi.NewRouter()
router.With(
httpin.NewInput(ListUsersInput{}),
).Get("/users", ListUsers)

r, _ := http.NewRequest("GET", "/users?is_member=1&age_range=18&age_range=60", nil)

rw := httptest.NewRecorder()
router.ServeHTTP(rw, r)
}

Output:

input: &main.ListUsersInput{IsMember:true, AgeRange:[]int{18, 60}}

Encoding

query will encode the field to the first key, i.e. KEY1, results in ?KEY1=VALUE.

Runable Example

package main

import (
"fmt"
"net/http/httputil"

"github.com/ggicci/httpin"
)

type ListUsersInput struct {
IsMember bool `in:"query=is_member"`
AgeRange []int `in:"query=age_range[],age_range"`
}

func main() {
input := &ListUsersInput{
IsMember: true,
AgeRange: []int{18, 60},
}
r, _ := httpin.NewRequest("GET", "/users", input)
data, _ := httputil.DumpRequest(r, false)
fmt.Printf("%s\n", data)
}

Output:

GET /users?age_range%5B%5D=18&age_range%5B%5D=60&is_member=true HTTP/1.1