header
header is a directive executor who decodes/encodes a field from/to HTTP headers, i.e. http.Request.Header
.
Signature
Name: "header"
Args: KEY1 [,KEY2 [,KEY3, ...]]
Decoding
header will examine values of the keys one by one (KEY1 -> KEY2 -> ...) from the HTTP headers, the first non-empty value will be used to set the corresponding field of the input struct.
caution
The keys will be normalized, see CanonicalHeaderKey
, e.g. the header key of Content-Type
and content-type
are the same, which works like case-insensitive.
Usage
type TokenInput struct {
Token string `in:"header=x-api-token,Authorization"`
}
Request (Header) | TokenInput |
---|---|
|
|
|
|
|
|
|
|
Runable Example
package main
import (
"fmt"
"io"
"net/http"
"net/http/httptest"
"github.com/ggicci/httpin"
"github.com/go-chi/chi/v5"
)
type UpdateAccountInput struct {
AccessToken string `in:"header=x-myapp-access-token"`
ClientVersion int `in:"header=x-myapp-client-version"`
}
func UpdateAccount(rw http.ResponseWriter, r *http.Request) {
input := r.Context().Value(httpin.Input).(*UpdateAccountInput)
fmt.Printf("input: %#v\n", input)
}
func main() {
router := chi.NewRouter()
router.With(
httpin.NewInput(UpdateAccountInput{}),
).Patch("/me", UpdateAccount)
r, _ := http.NewRequest("PATCH", "/me", nil)
r.Header.Set("x-myapp-access-token", "rainbow")
r.Header.Set("X-Myapp-Client-Version", "284")
r.Body = io.NopCloser(nil)
rw := httptest.NewRecorder()
router.ServeHTTP(rw, r)
}
Output:
input: &main.UpdateAccountInput{AccessToken:"rainbow", ClientVersion:284}
Encoding
header will encode the field value to the HTTP headers, the first key will be used, i.e. KEY1
, results in http.Request.Header.Set(KEY1, VALUE)
.
Runable Example
package main
import (
"fmt"
"net/http/httputil"
"github.com/ggicci/httpin"
)
type UpdateAccountInput struct {
AccessToken string `in:"header=x-myapp-access-token"`
ClientVersion int `in:"header=x-myapp-client-version"`
}
func main() {
payload := &UpdateAccountInput{
AccessToken: "rainbow",
ClientVersion: 813,
}
r, _ := httpin.NewRequest("PATCH", "/me", payload)
data, _ := httputil.DumpRequest(r, true)
fmt.Printf("%s\n", data)
}
Output:
PATCH /me HTTP/1.1
X-Myapp-Access-Token: rainbow
X-Myapp-Client-Version: 813