Skip to content

"binding element must be a struct" introduced with path params binding #1356

@andreiavrammsd

Description

@andreiavrammsd

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/1

Working 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")
}

Version/commit

858270f

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions