-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Description
Issue Description
This is simillar to #988 and introduced by 858270f in a specific situation: taking the address of your struct twice and sending it to bind.
u := &user{}
c.Bind(&u)Because of the newly introduced params binding, when the struct's type is checked, it fails here:
func (b *DefaultBinder) bindData(ptr interface{}, data map[string][]string, tag string) error {
typ := reflect.TypeOf(ptr).Elem()
val := reflect.ValueOf(ptr).Elem()
if typ.Kind() != reflect.Struct {
return errors.New("binding element must be a struct")
}
Before the params binding was introduced, bindData was not called for POST/PUT/PATCH, because for these methods you directly decode the body into the given struct.
And a mention: If you have id both as path param and json property in the request body, the value from the body will overwrite the one from the path. This could lead to confusion and bugs in projects.
Checklist
- Dependencies installed
- No typos
- Searched existing issues and docs
Expected behaviour
If this is known and planned for next major version, than it's OK, else compatibility should not be broken.
Actual behaviour
See Expected behaviour
Steps to reproduce
Take the address of the struct sent at bind twice and make a request to a server (see Working code to debug).
curl -X PUT -H "Content-Type: application/json" -d '{"name":"John"}' localhost:8811/users/1Working code to debug
package main
import (
"github.com/labstack/echo/v4"
"github.com/labstack/echo/v4/middleware"
"github.com/labstack/gommon/log"
)
type user struct {
ID int `json:"id" param:"id"`
Name string `json:"name"`
}
func main() {
s := echo.New()
s.Use(middleware.Logger())
s.PUT("/users/:id", func(c echo.Context) error {
u := &user{}
if err := c.Bind(&u); err != nil {
log.Fatal(err)
}
log.Print(u)
return nil
})
s.Start(":8811")
}