Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

how to binding param and json #2535

Open
lun3322 opened this issue Oct 20, 2020 · 17 comments
Open

how to binding param and json #2535

lun3322 opened this issue Oct 20, 2020 · 17 comments

Comments

@lun3322
Copy link

lun3322 commented Oct 20, 2020

How to reproduce

package main

import (
	"github.com/gin-gonic/gin"
)

type UserRequest struct {
	Id       int    `uri:"id"`
	Nickname string `json:"nickname"`
	Mobile   string `json:"mobile"`
	Email    string `json:"email"`
}

func main() {
	g := gin.Default()
	g.GET("/user/:id", func(c *gin.Context) {
		// how to do?
	})
	g.Run(":9000")
}
curl -v -X POST \
  http://localhost:8080/user/12\
  -H 'content-type: application/json' \
  -d '{"nickname": "nickname1","mobile": "133232323232","email": "fqlw@qqq.com"

@Doarakko
Copy link
Contributor

Bind twice.

	g.POST("/user/:id", func(c *gin.Context) {
		var u UserRequest 

		if err := c.ShouldBindUri(&u); err != nil {
			c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
			return
		}

		if err := c.ShouldBindJSON(&u); err != nil {
			c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
			return
		}
		fmt.Printf("id: %d nickname: %s mobile: %s email: %s\n", u.Id, u.Nickname, u.Mobile, u.Email)

		c.JSON(http.StatusNoContent, nil)
	})

This is the related issue.
#1824

Please tell me if there is another good way!

@lun3322
Copy link
Author

lun3322 commented Oct 21, 2020

I also want to know if there is another way

@agmadt
Copy link

agmadt commented Oct 21, 2020

Can't you do something like

u.ID = c.Param("id")?

@lun3322
Copy link
Author

lun3322 commented Oct 22, 2020

It seems that it is not possible to bind successfully by calling the API once.

@tunhuit
Copy link

tunhuit commented Jun 23, 2021

Bind twice.

	g.POST("/user/:id", func(c *gin.Context) {
		var u UserRequest 

		if err := c.ShouldBindUri(&u); err != nil {
			c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
			return
		}

		if err := c.ShouldBindJSON(&u); err != nil {
			c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
			return
		}
		fmt.Printf("id: %d nickname: %s mobile: %s email: %s\n", u.Id, u.Nickname, u.Mobile, u.Email)

		c.JSON(http.StatusNoContent, nil)
	})

This is the related issue.
#1824

Please tell me if there is another good way!

Only work with non-required fields. Is there anyway with required fields?

type UpdateRequest struct {
    ID   uint64 `uri:"id" binding:"required"`
    Data struct {
        Name string `json:"name" binding:"required"`
        Slug string `json:"slug" binding:"required"`
    }
}

@NicklasWallgren
Copy link

As mentioned above, the workaround (bind twice) doesn't work with required fields.

@jlaneve
Copy link

jlaneve commented May 14, 2022

+1 on this. Any updates or workarounds for required fields?

@uedayuji
Copy link

+1

6 similar comments
@tiredsosha
Copy link

+1

@murfidaz
Copy link

+1

@neopoleones
Copy link

+1

@alahaiyo
Copy link

alahaiyo commented Jan 3, 2023

+1

@zhouguangming
Copy link

+1

@c5ms
Copy link

c5ms commented Jun 25, 2023

+1

@c5ms
Copy link

c5ms commented Jul 14, 2023

ok here is an example :

// here ,we can use this struct in get method again.
type UserGetRequest struct {
	Id models.Id `uri:"id" binding:"required"`
}

type UserUpdateRequest struct {
	Nickname string `json:"nickname" `
}



func UserGet(context *gin.Context, domain *domains.Context) {
	var (
		locator = new(UserGetRequest)
	)

	if err = context.BindUri(locator); err != nil {
		return
	}

	if user, err = upms.UserGet(domain, locator.Id); err == nil {
		 ... 
	}
	return
}


func UserUpdate(context *gin.Context)  {
	var (
                locator  = new(UserGetRequest)
		request = new(UserUpdateRequest)
	)

	if err = context.BindUri(&params); err != nil {
		return
	}

	if err = context.BindJSON(&request); err != nil {
		return
	}

	var action = upms.UserUpdateAction{
		Nickname: request.Nickname,
	}

	if user, err = upms.UserUpdate(domain, locator.Id, action); err == nil {
		.....
	}

	return
}

@abawchen
Copy link

Is it a good idea to support something like requried_in=json, required_in=uri? If it makes sense, I would like to create a pr.

@KarlsMaranjs
Copy link

This worked for me:

ok here is an example :

// here ,we can use this struct in get method again.
type UserGetRequest struct {
	Id models.Id `uri:"id" binding:"required"`
}

type UserUpdateRequest struct {
	Nickname string `json:"nickname" `
}


func UserUpdate(context *gin.Context)  {
	var (
                locator  = new(UserGetRequest)
		request = new(UserUpdateRequest)
	)

	if err = context.BindUri(&params); err != nil {
		return
	}

	if err = context.BindJSON(&request); err != nil {
		return
	}

	var action = upms.UserUpdateAction{
		Nickname: request.Nickname,
	}

	if user, err = upms.UserUpdate(domain, locator.Id, action); err == nil {
		.....
	}

	return
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests