default
Introduced in v0.8.0.
default is a directive executor who populates unset fields to their default values while decoding, and populates zero fields to their default values while encoding.
- unset fields: fields that have not been set by former directives.
- zero fields: values are zero values, such as
0
,""
,false
,nil
,[]
,map[]
,struct{}
.
Signature
Name: "default"
Args: VAL1 [,VAL2 [,VAL3, ...]]
For an array type of value, you can use comma to separate the items in the array. So the presence of comma in an array item can lead to unexpected behavior.
Decoding
default will examine if the field has already been set by former directives. If not, it will set the field to the given value.
Usage
type ListTasksQuery struct {
Page int `in:"query=page;default=1"`
PerPage int `in:"query=per_page;default=20"`
StateList []string `in:"query=state;default=pending,running"`
}
Request | ListTasksQuery |
---|---|
|
|
|
|
Runable Example
package main
import (
"fmt"
"net/http"
"net/http/httptest"
"github.com/ggicci/httpin"
"github.com/go-chi/chi/v5"
)
type ListTasksQuery struct {
Page int `in:"query=page;default=1"`
PerPage int `in:"query=per_page;default=20"`
StateList []string `in:"query=state;default=pending,running"`
}
func ListTasks(rw http.ResponseWriter, r *http.Request) {
input := r.Context().Value(httpin.Input).(*ListTasksQuery)
fmt.Printf("input: %#v\n", input)
}
func main() {
router := chi.NewRouter()
router.With(
httpin.NewInput(ListTasksQuery{}),
).Get("/tasks", ListTasks)
r, _ := http.NewRequest("GET", "/tasks?page=0", nil)
rw := httptest.NewRecorder()
router.ServeHTTP(rw, r)
}
Output:
input: &main.ListTasksQuery{Page:0, PerPage:20, StateList:[]string{"pending", "running"}}
Encoding
default will examine if the field is a zero value. If so, it will set the field to the given value.
Since httpin runs the directives in the order of their appearance in the struct, you should always define the order of the directives based on decoding requirements, default should be placed after directives like query and path that set the field values.
In order to make it works for encoding as well, httpin will reorder the directives internally for encoding. The final order of directives will be:
For example, the above struct will be reordered to:
type ListTasksQuery struct {
Page int `in:"default=1;query=page"`
PerPage int `in:"default=20;query=per_page"`
}
Runable Example
package main
import (
"fmt"
"net/http/httputil"
"github.com/ggicci/httpin"
)
type ListTasksQuery struct {
Page int `in:"query=page;default=1"`
PerPage int `in:"query=per_page;default=20"`
StateList []string `in:"query=state;default=pending,running"`
}
func main() {
input := &ListTasksQuery{Page: 3}
r, _ := httpin.NewRequest("GET", "/tasks", input)
data, _ := httputil.DumpRequest(r, true)
fmt.Printf("%s\n", data)
}
Output:
GET /tasks?page=3&per_page=20&state=pending&state=running HTTP/1.1