I have this routes:
r.GET("/drivers/price", ctrl.GetDriversPrice)
r.GET("/drivers/:id", ctrl.GetDriver)
So when I call http://.../drivers/price, I'm routed to ctrl.GetDriver. How can I make to get routed to ctrl.GetDriversPrice?
Gin will panic because wildcard route conflicts with existing route, maybe your code is not like the snippet . Could you post your example code?

Yes, It panics. That's my question about. For example in Ruby On Rails, if those routes are defined
r.GET("/drivers/price", ctrl.GetDriversPrice)
r.GET("/drivers/:id", ctrl.GetDriver)
if you go to http://.../drivers/price the router will take it as a route and it wont take /price as a wildcard :id
Gin requires routes to be unambiguous. It's one of the ups and downs of a non regexp based routing.
Not the best solution but you can use the strings.EqualFold function from "strings" package with c.Request.RequestURI function for checking the URI.
```go
package main
import (
"fmt"
"github.com/gin-gonic/gin"
"strings"
)
func main() {
r := gin.Default()
r.GET("/drivers/:id", GetDriverHandler)
r.Run(":3000")
}
func GetDriverHandler(c *gin.Context) {
//fmt.Println(c.Request.RequestURI)
if strings.EqualFold(c.Request.RequestURI, "/drivers/price") {
fmt.Fprintf(c.Writer, "GetDriversPrice")
} else {
id := c.Param("id")
fmt.Fprintf(c.Writer, "GetDriversId "+id)
}
}
````
or something like
// main.go
r.GET("/drivers/:id", ctrl.GetDriver)
...
// ctrl/handlers.go
func GetDriver(c *gin.Context) {
if c.Request.RequestURI == "/drivers/price" {
GetDriversPrice(c)
return
}
...
}
...
how to use middleware in your solution ?
example:
r.GET("/drivers/price", ctrl.GetDriversPrice)
r.GET("/drivers/:id", ctrl.AuthRequired, ctrl.GetDriver)
@ferluk it feels like a bummer if you're accustomed to leveraging the order of declared paths as it's implemented in other routing libs, but with gin you can consider flipping the conflicting route.
r.GET("/price/drivers", ctrl.GetDriversPrice)
r.GET("/drivers/:id", ctrl.AuthRequired, ctrl.GetDriver)
Unfortunately it sometimes means that routes which feel like they should hang off the same Group sharing a set of common middleware can't, and our middleware usage can become repetitive like below where ctrl.AuthRequired is repeated twice (unless moveable to a higher group)...
priceRoutes := r.Group("/price").Use(ctrl.AuthRequired)
{
priceRoutes.GET("/drivers", ctrl.GetDriversPrice)
}
driverRoutes := r.Group("/drivers").Use(ctrl.AuthRequired)
{
// cannot hang export off of driveRoutes due to conflict with /:id
// driverRoutes.GET("/price", ctrl.GetDriversPrice)
driverRoutes.GET("/:id", ctrl.GetDriver)
}
However I still think this ^ is likely better than nesting routing logic for pricing in another handler, ideally route definitions can inform of all url routing rather than overloading handlers with route logic which has been suggested by others.
Another option is to increase the specificity of your drivers/:id endpoint...
r.GET("/drivers/price", ctrl.GetDriversPrice)
r.GET("/drivers/id/:id", ctrl.AuthRequired, ctrl.GetDriver)
That ^ may feel less congenial to the typical restful pattern of resources/:resourceID but at least grouping middleware is a bit cleaner...
v1 := r.Group("/v1").Use(ctrl.AuthRequired)
driverRoutes := v1.Group("/drivers").Use(ctrl.DriverMiddleware)
{
driverRoutes.GET("/price", ctrl.GetDriversPrice)
driverRoutes.GET("/id/:id", ctrl.GetDriver)
}