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 use middleware to convert parameter values #1866

Open
strivefatup opened this issue Apr 24, 2019 · 6 comments
Open

How to use middleware to convert parameter values #1866

strivefatup opened this issue Apr 24, 2019 · 6 comments

Comments

@strivefatup
Copy link

I want to implement such a function, convert the id parameter in the following route into an int type, what should I do?

package main

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

func main() {
	r := gin.Default()
        r.use(TestMiddleware)
	r.GET("/test/:id", func(c *gin.Context) {
		c.JSON(200, gin.H{
			"message": "pong",
		})
	})
	r.Run() // listen and serve on 0.0.0.0:8080
}

func TestMiddleware(c *gin.Context) {
     //I want to change the type of this id parameter from string to int type here.what should I do?
    c.Next()
}
@Dimitriy14
Copy link

Use strconv:
yourValue, err := strconv.ParseInt(c.Param("id"), 10, 64)

@strivefatup
Copy link
Author

使用strconv:
yourValue, err := strconv.ParseInt(c.Param("id"), 10, 64)

I know this method,This is not the result I want,
example:

//I request this address:127.0.0.1:8080/test/5
id := c.Param("id") //The value of id is "5",this is string,I want to convert to int,
//then,When I get it again, it becomes my converted value.
c.Param("id") 
//The purpose of my doing this is that I don't want to have to write duplicate code
//If I have other api, the id parameter also needs to be converted, I have to write it once.
//I don't know how to write

Thanks

@dmarkham
Copy link
Contributor

@strivefatup So the way I solve this is with a few helper functions I keep in a path helper package
I think you can see what all my other helpers would look like based on this sample.

func GetPathInt(c *gin.Context, name string) (int, error) {
   val := c.Params.ByName(name)
   if val == "" {
      return 0, errors.New(name + " path parameter value is empty or not specified")
   }
   return strconv.Atoi(val)
}

@strivefatup
Copy link
Author

@strivefatup So the way I solve this is with a few helper functions I keep in a path helper package
I think you can see what all my other helpers would look like based on this sample.

func GetPathInt(c *gin.Context, name string) (int, error) {
   val := c.Params.ByName(name)
   if val == "" {
      return 0, errors.New(name + " path parameter value is empty or not specified")
   }
   return strconv.Atoi(val)
}

Your method is also very good,It’s perfect if can change directly in the middleware,Thanks.

@guonaihong
Copy link
Contributor

guonaihong commented Jun 11, 2019

You can use the shouldbindurl function

package main

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

type Person struct {
        ID int `uri:"id"`
}

func main() {
        r := gin.Default()
        r.GET("/test/:id", func(c *gin.Context) {
                person := Person{}

                if err := c.ShouldBindUri(&person); err != nil {
                        c.JSON(400, gin.H{"msg": err})
                        return
                }

                c.JSON(200, gin.H{
                        "ID": person.ID,
                })
        })
        r.Run() // listen and serve on 0.0.0.0:8080
}
// client
// curl -X GET 127.0.0.1:8080/test/123
// output
// {"ID":123}

guonaihong added a commit to guonaihong/gin that referenced this issue Jun 14, 2019
```go
package main

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

func main() {
	r := gin.Default()
	r.GET("/:int/:string/:float/:bool/:duration", func(c *gin.Context) {
		var i int
		var err error

		err = c.ParamVar("int", &i)
		fmt.Printf("%v, %v\n", i, err)

		var b bool
		err = c.ParamVar("bool", &b)
		fmt.Printf("%v, %v\n", b, err)

		var f float64
		err = c.ParamVar("float", &f)
		fmt.Printf("%v, %v\n", f, err)

		var s string
		err = c.ParamVar("string", &s)
		fmt.Printf("%v, %v\n", s, err)

		var d time.Duration
		err = c.ParamVar("duration", &d)
		fmt.Printf("%v, %v\n", d, err)
	})

	r.Run()
	return
}

// client
// curl -X GET 127.0.0.1:8080/1/test/3.14/true/1s
```
@JABvzla
Copy link

JABvzla commented Oct 22, 2019

I'm not sure if this works for you, but you can create values on your gin.Context

First create a yourNewValue from a middleware

// Middleware
func ExampleMiddleware() gin.HandlerFunc  {
	return func(c *gin.Context) {
		c.Set("yourNewValue", "value")
		c.Next()
	}
}

Then get that value from your controller

// Controller
func(c *gin.Context) {
	c.JSON(200, gin.H{
		"ID": c.MustGet("yourNewValue"),
	})
}

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

5 participants