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"
.
Comment From: qimingweng
cc @moberemk
Comment From: q191201771
c.Request.URL.Path may satisfied for you
Comment From: qimingweng
@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"
Comment From: q191201771
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)
}
})
Comment From: qimingweng
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.
Comment From: javierprovecho
@qimingweng maybe engine.Routes()
can help you... :wink:
EDIT: checkout https://godoc.org/github.com/gin-gonic/gin#Engine.Routes
EDIT: reopen if this doesn't help you.
Comment From: qimingweng
@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?
Comment From: javierprovecho
@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...
Comment From: qimingweng
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.
Comment From: itsjamie
@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.
Comment From: itsjamie
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,
)
Comment From: qimingweng
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...)...)
}
Comment From: roychowdhuryrohit-dev
Is it possible to access the basepath from context?
Comment From: eastrd
If you want to get the complete raw string after domain, including the GET parameters and such:
c.Request.URL.String()
Comment From: jackieli-tes
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
Comment From: sougat818
c.FullPath()
doesn't seem to return the parameters. c.Request.URL.String()
still does