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

Unable to validate both query parameters and request body using a single struct in Gin application #3635

Open
Manojnaik1 opened this issue Jun 5, 2023 · 1 comment

Comments

@Manojnaik1
Copy link

Description

I am facing an issue where I am unable to validate both query parameters and the request body using a single struct in my Gin application. Currently, the ShouldBind method only validates the request body, while query parameters are not being validated.

Steps to Reproduce:
Define a struct, FlowRequest, to represent the request data:
type FlowRequest struct {
TenantID int json:"tenant_id" uri:"tenantID" binding:"required"
Name string json:"name" binding:"required"
}

Use the FlowRequest struct in the Gin handler function:
func handleRequest(c *gin.Context) {
var req FlowRequest

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

// Process the request and return the response
c.JSON(http.StatusOK, gin.H{"message": "Request processed successfully"})

}

Make a request to the API endpoint with both the path parameter tenantID and the request body containing name:
POST /api/flow/123
Content-Type: application/json

{
"name": "John Doe"
}

Observe that the validation for the Name field in the request body is working correctly, but the TenantID path parameter is not being validated.

Expected Behavior
I expect both the query parameters and the request body to be validated according to the defined struct tags.

Actual Behavior
Only the request body is being validated, while query parameters are not being validated.

Environment
go version: go1.20.4
Please let me know if there are any further details or modifications you would like to make to the issue description.

@AhmadGhadiri
Copy link

AhmadGhadiri commented Jun 12, 2023

I think for validating the param and body, a single function/struct combo can not be used. The ShouldBindUri function can be used per this PR #1612
Something like this worked for me:

// Used for validating params in URI
type RequestUri struct {
	TenantID int `uri:"tenant_id" binding:"required"`
}

// Used for Body 
type RequestBody struct {
	Name string `json:"name" binding:"required"`
}

func main() {
	g := gin.Default()
	g.POST("/api/flow/:tenant_id", func(c *gin.Context) {
		var uri RequestUri
		var body RequestBody
		if err := c.ShouldBindUri(&uri); err != nil {
			c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		} else if err := c.ShouldBind(&body); err != nil {
			c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		} else {
			c.JSON(http.StatusOK, gin.H{"message": fmt.Sprintf("Hello %v, this is the id: %v", body.Name, uri.TenantID)})
		}
	})
	g.Run(":9000")
}

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

2 participants