body
body is a directive executor who decodes/encodes a field from/to the body of the request, i.e. http.Request.Body
, JSON and XML formats are supported.
Signature
Name: "body"
Args: BODY_TYPE
Supported BODY_TYPE are:
- json: parses the body as an JSON object
- xml: parses the body as an XML object
If BODY_TYPE were not specified, json
will be used.
Decoding
body will read the content of the request body and parses it as BODY_TYPE
into the corresponding field of the struct.
Usage
type User struct {
Login string `json:"login"`
Gender string `json:"gender"`
}
type CreateUserInput struct {
Payload *User `in:"body=json"` // use "body=xml" for XML formatted body
}
Request (Body) | CreateUserInput |
---|---|
|
|
Runable Example
package main
import (
"fmt"
"io"
"net/http"
"net/http/httptest"
"strings"
"github.com/ggicci/httpin"
httpin_integration "github.com/ggicci/httpin/integration"
"github.com/go-chi/chi/v5"
)
type UserPatch struct {
Display string `json:"display"`
Email string `json:"email"`
IsAdmin bool `json:"is_admin"`
}
type UpdateUserInput struct {
ID string `in:"path=id"` // NOTE: register a path directive before using
Payload UserPatch `in:"body=json"`
}
func UpdateUserHandler(rw http.ResponseWriter, r *http.Request) {
input := r.Context().Value(httpin.Input).(*UpdateUserInput)
fmt.Printf("input: %#v\n", input)
}
func init() {
httpin_integration.UseGochiURLParam("path", chi.URLParam)
}
func main() {
router := chi.NewRouter()
router.With(
httpin.NewInput(UpdateUserInput{}),
).Put("/users/{id}", UpdateUserHandler)
r, _ := http.NewRequest("PUT", "/users/19911110", nil)
r.Body = io.NopCloser(strings.NewReader(`{
"display": "Ggicci Never Cry",
"email": "secret_@xxx.com",
"is_admin": true
}`))
rw := httptest.NewRecorder()
router.ServeHTTP(rw, r)
}
Output:
input: &main.UpdateUserInput{
ID:"19911110",
Payload:main.UserPatch{
Display:"Ggicci Never Cry",
Email:"secret_@xxx.com", IsAdmin:true
}
}
Encoding
body will encode the corresponding field of the struct into the body of the response, in BODY_TYPE
format.
Runable Example
package main
import (
"fmt"
"net/http/httputil"
"github.com/ggicci/httpin"
)
type UserPatch struct {
Display string `json:"display"`
Email string `json:"email"`
IsAdmin bool `json:"is_admin"`
}
type UpdateUserInput struct {
ID string `in:"path=id"`
Payload UserPatch `in:"body=json"`
}
func main() {
input := &UpdateUserInput{
ID: "ggicci",
Payload: UserPatch{
Display: "Ggicci",
Email: "secret_@xxx.com",
IsAdmin: true,
},
}
r, _ := httpin.NewRequest("PATCH", "/users/{id}", input)
data, _ := httputil.DumpRequest(r, true)
fmt.Printf("%s\n", data)
}
Output:
PATCH /users/ggicci HTTP/1.1
Content-Type: application/json
{"display":"Ggicci","email":"secret_@xxx.com","is_admin":true}
Custom Body Format
Call RegisterBodyFormat
to register a new body format/serializer to httpin.
For example, the default JSON decoder is borrowed from Go's standard encoding/json
package.
If you want to use a different JSON decoder, you can replace it by using the following code:
import httpin_core "github.com/ggicci/httpin/core"
func init() {
httpin_core.RegisterBodyFormat("json", &MyPerformanentJSONSerializer{})
}