gin-gonic/gin 🥤
Integrations
You have to create a gin middleware on your own.
In the following demo code, BindInput
is a good example to start.
Run Demo
package main
import (
"context"
"errors"
"fmt"
"net/http"
"net/http/httptest"
"github.com/ggicci/httpin"
"github.com/gin-gonic/gin"
)
// BindInput instances an httpin engine for an input struct as a gin middleware.
func BindInput(inputStruct interface{}) gin.HandlerFunc {
engine, err := httpin.New(inputStruct)
if err != nil {
panic(err)
}
return func(c *gin.Context) {
input, err := engine.Decode(c.Request)
if err != nil {
var invalidFieldError *httpin.InvalidFieldError
if errors.As(err, &invalidFieldError) {
c.AbortWithStatusJSON(http.StatusBadRequest, invalidFieldError)
return
}
c.AbortWithStatus(http.StatusInternalServerError)
return
}
ctx := context.WithValue(c.Request.Context(), httpin.Input, input)
c.Request = c.Request.WithContext(ctx)
c.Next()
}
}
type ListUsersInput struct {
Gender string `in:"query=gender"`
AgeRange []int `in:"query=age_range"`
IsMember bool `in:"query=is_member"`
}
func ListUsers(c *gin.Context) {
input := c.Request.Context().Value(httpin.Input).(*ListUsersInput)
fmt.Printf("input: %#v\n", input)
}
func main() {
router := gin.New()
// Bind input struct with handler.
router.GET("/users", BindInput(ListUsersInput{}), ListUsers)
r, _ := http.NewRequest("GET", "/users?gender=male&age_range=18&age_range=24&is_member=1", nil)
rw := httptest.NewRecorder()
router.ServeHTTP(rw, r)
}
Since it will run timeout on the Go Playground. I removed the Run
button for the above demo code.
You can test the above snippet by using the following command on your local host:
mkdir /tmp/test && cd $_
touch main.go
# then COPY & PASTE the above code to main.go
go mod init test
go mod tidy
go run main.go
The output on my machine looks like this:
[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
- using env: export GIN_MODE=release
- using code: gin.SetMode(gin.ReleaseMode)
[GIN-debug] GET /users --> main.ListUsers (2 handlers)
input: &main.ListUsersInput{Gender:"male", AgeRange:[]int{18, 24}, IsMember:true}