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

panic: wildcard route conflicts with existing children #205

Closed
carr123 opened this issue Feb 5, 2015 · 10 comments · Fixed by #2663
Closed

panic: wildcard route conflicts with existing children #205

carr123 opened this issue Feb 5, 2015 · 10 comments · Fixed by #2663

Comments

@carr123
Copy link

carr123 commented Feb 5, 2015

router.GET("/api/test/basic_data_set_link", control.GetBasicDataSetLink())
router.GET("/api/:user_id/requestedgroups", control.GetRequestedGroups()) 

the above two lines conflict, and cause panic.
but it seems no problem. so, what's wrong with my code ??
thanks.

@javierprovecho
Copy link
Member

Hello @carr123 , this is not a problem or issue from Gin, is from httprouter instead because how its made.

I suggest the following:

// ...
router.GET("/api/:user_id/requestedgroups", control.GetRequestedGroups) 
// ...
    if strings.HasPrefix(c.Request.RequestURI, "/api/test/basic_data_set_link") {
        return control.GetBasicDataSetLink(c)
    } else {
        // your original "control.GetRequestedGroups" hanlder code ...
    }
// ...

@wrunk
Copy link

wrunk commented Feb 24, 2015

Thanks @javierprovecho this is helpful (and thanks for this project it is great). I am wondering if httprouter is too simple for mainstream use, and if you guys plan to support other routers like https://github.com/dimfeld/httptreemux ? We have the same problem as carr123 and would prefer to avoid too many wrappers. Thanks.

@olebedev
Copy link

@wrunk +1

@javierprovecho
Copy link
Member

@wrunk no plans at the moment, everything of gin is around httprouter, and so speed and performance. Thank you for discovering me httptreeremux, I liked it!, I should compare speed against httprouter, and if it doesn't go so much slower, I think I will give it a try.

Closing this issue.

@samehkhaliel
Copy link

Is there any plans to support httptreeremux soon ?

@ptman
Copy link

ptman commented Nov 17, 2015

@javierprovecho @manucorporat #205 (comment) is really helpful for me, but how would you set different middleware for /:key (catch-all) and /admin? I think I've looked through all the relevant httprouter and gin issues

@beef9999
Copy link

beef9999 commented Apr 21, 2017

I deleted those cursing comments, and hereby give out my solution, hopefully it would help people.

After all, it's your own project. You didn't force us to use it.

    router.GET("/v1/images/:path1", GetHandler)           //      /v1/images/detail
    router.GET("/v1/images/:path1/:path2", GetHandler)    //      /v1/images/<id>/history

func GetHandler(c *gin.Context) {
    path1 := c.Param("path1")
    path2 := c.Param("path2")

    if path1 == "detail" && path2 == "" {
        Detail(c)
    } else if path1 != "" && path2 == "history" {
        imageId := path1
        History(c, imageId)
    } else {
        HandleHttpError(c, NewHttpError(404, "Page not found"))
    }
}

@kofj
Copy link

kofj commented Sep 1, 2017

I need wildcard route at root, like /:any at my url shortener project. But gin not support it, so I use router.NoRoute.

@PercyPham
Copy link

PercyPham commented Sep 21, 2020

This should not be closed, those solutions are not ideal. In my case, I have to use middleware in between, for example:

router.GET("/active", findActive)

router.Use(someMiddleware())

router.GET(":id", findByID)

It would be very cumbersome to deal with this using solutions above.

Edited:

I made a workaround like this:

router.Get("/:id", h.findActive, someMiddleware(), h.findByID)

And in findActive():

func (h handler) findActive(c *gin.Context) {
  id := c.Param("id")
  if id == "active" {
    active := h.service.FindActive(c.Request.Context())
    response.Success(c, active)
    c.Abort()
    return
  }
  c.Next()
}

However, I still find it ugly and not straight forward, hope Gin will implement someway else in future.

@bh7cw
Copy link

bh7cw commented Oct 4, 2020

This should not be closed, those solutions are not ideal. In my case, I have to use middleware in between, for example:

router.GET("/active", findActive)

router.Use(someMiddleware())

router.GET(":id", findByID)

It would be very cumbersome to deal with this using solutions above.

Edited:

I made a workaround like this:

router.Get("/:id", h.findActive, someMiddleware(), h.findByID)

And in findActive():

func (h handler) findActive(c *gin.Context) {
  id := c.Param("id")
  if id == "active" {
    active := h.service.GetActive(c.Request.Context())
    response.Success(c, active)
    c.Abort()
    return
  }
  c.Next()
}

However, I still find it ugly and not straight forward, hope Gin will implement someway else in future.

This is great. I meet the similar problem:

  • /v1/user/self: basic auth
  • /v1/user/:id: public

The conflict panics.
This solution works for my issue.

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