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

[question] Is it possible to retrieve the raw string from the route? #584

Closed
qimingweng opened this issue Apr 13, 2016 · 16 comments
Closed
Assignees
Labels

Comments

@qimingweng
Copy link

If a route is defined as

engine.POST("/endpoint/:id/something", ...)

Is it possible, somewhere in the gin.Context object, to retrieve the string "/endpoint/:id/something" (different from, for example "/endpoint/123/something".

@qimingweng
Copy link
Author

cc @moberemk

@q191201771
Copy link

c.Request.URL.Path may satisfied for you

@qimingweng
Copy link
Author

@q191201771 I'm specifically asking for the string without the absolute parameters but the parameters defined with a colon. For example ":id" instead of "123"

@q191201771
Copy link

   const path = "/endpoint/:id/something"
    e.GET(path, func(c *gin.Context) {
        log.Println(path)
        log.Println(c.Param("id"))
        log.Println(c.Request.URL.Path)
        c.Set("path", path)
        if p, exist := c.Get("path"); exist {
            log.Println(p)
        }
    })

@qimingweng
Copy link
Author

I'm hoping that gin stores the original string somewhere in the internals so that I don't have to manage path string management myself. Yes. I could keep it in variables or even print out the literal path within each route.

@javierprovecho
Copy link
Member

javierprovecho commented Apr 14, 2016

@qimingweng maybe engine.Routes() can help you... 😉

EDIT: checkout https://godoc.org/github.com/gin-gonic/gin#Engine.Routes

EDIT: reopen if this doesn't help you.

@qimingweng
Copy link
Author

@javierprovecho Hi, I'm basically asking if there was a way to see, in the Context, how to get the RouteInfo of this request.

Short of parsing the current url request against all the routes in engine.Routes a second time, is there another way to find this info? If not, is there an exposed function to do that parsing?

@javierprovecho
Copy link
Member

@qimingweng no, there is no exported field or function to get that information on an active request. Why do you need to know that on request time? I'm sure there is a better way...

@qimingweng
Copy link
Author

We want to provide better logging on each request. But the url Path is too specific.

I suppose we could use a handler generator to encapsulate that data as we define the routes, but I would perfer if I didn't need to repeat code (usually repetition is where bugs come in). Also this requires a large overhaul of all existing routes.

@itsjamie
Copy link
Contributor

@javierprovecho I'm also doing this, specifically for instrumentation of the API with Prometheus, I'd like to label the path using the original string. Right now, you have to store the path in the handler, and then use that, which prevents you from being able to use inline gin.HandlerFunc.

Ideally, that path would be accessible on the Context.

@itsjamie
Copy link
Contributor

itsjamie commented Jun 10, 2016

Essentially, I've created a middleware that sets it in the context to solve the problem for me that utilizes it. But it would be great to not have to duplicate it.

Ends up with a definition like

singular.POST(
    "/activate",
    middleware.PathInfo(singular.BasePath()+"/activate"),
    ctrl.activateUser,
)

@qimingweng
Copy link
Author

At https://github.com/edusight, we ended up writing a wrapper function to do this without repeating a string.

// We needed an interface because we attach handlers to both engines
// as well as route groups
type routerGroupOrEngine interface {
    BasePath() string
    Handle(string, string, ...gin.HandlerFunc)
}

func trackPath(path string) gin.HandlerFunc {
    return func(c *gin.Context) {
        t := time.Now()

        c.Next()

        latency := time.Since(t)

        // Logging some data however you want, in this case we care about the latency and the path
        logEntry(latency, path)
    }
}

func addRouteToRouteGroupOrEngine(group routerGroupOrEngine, httpType string, path string, handlers ...gin.HandlerFunc) {
    fullPath := group.BasePath() + path
    allHandlers := []gin.HandlerFunc{
        trackPath(fullPath),
    }

    // The double spread operator is a little awkward so if you have ideas I'm open to changing this
    group.Handle(httpType, path, append(allHandlers, handlers...)...)
}

@roychowdhuryrohit-dev
Copy link

Is it possible to access the basepath from context?

@eastrd
Copy link

eastrd commented Nov 26, 2019

If you want to get the complete raw string after domain, including the GET parameters and such:
c.Request.URL.String()

@jackieli-tes
Copy link

For those who are still searching for an answer, you can use c.FullPath(): https://pkg.go.dev/github.com/gin-gonic/gin#Context.FullPath

@sougat818
Copy link

c.FullPath() doesn't seem to return the parameters. c.Request.URL.String() still does

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

No branches or pull requests

8 participants