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

segment conflicts with existing wildcard #1301

Closed
68696c6c opened this issue Mar 31, 2018 · 10 comments · Fixed by #2663
Closed

segment conflicts with existing wildcard #1301

68696c6c opened this issue Mar 31, 2018 · 10 comments · Fixed by #2663

Comments

@68696c6c
Copy link

I found a few other issues that look like they are related to this problem, but they are all closed and I'm not sure what the status of this bug is, so I'm making a new issue here...

As an example I've defined two routes, one to get a user by their ID, and another to get a user by their email:

	apiRoutes := r.Engine.Group("/api")
	apiRoutes.GET("/users/:id", GetUser)
	apiRoutes.GET("/users/email/:email", GetUser)

When I try and build, I get this error:

panic: path segment 'email/:email' conflicts with existing wildcard ':id' in path '/api/users/email/:email'

The problem is that these routes are NOT ambiguous and shouldn't conflict. I'm using Gin in several APIs and run into this problem in all of them in various ways. The above code is just a simplified demonstration of the bug.

Based on the closed issues I've found here:
#205
#388

That last issue referenced this open issue in httprouter:
julienschmidt/httprouter#73

...but that issue hasn't been updated since 2015...

So it seems the Gin team is aware of this bug, but it isn't clear whether or not it's going to be fixed. I'm just posting this to get some clarity on the problem.

Thanks!

@nazwa
Copy link

nazwa commented Apr 24, 2018

Hi @68696c6c - it's not really a bug, but a known limitation. The downside of not using regular expressions for route matching is that paths have to be unique.

Unfortunately afaik this behavior is not going to change any time soon.

@nazwa nazwa closed this as completed Apr 24, 2018
@68696c6c
Copy link
Author

Understood, thank you.

However, I was fiddling with this more today and found a workaround that I wanted to share here in case anyone else comes across this issue.

If I change my routes to look like this, everything works fine:

        apiRoutes := r.Engine.Group("/api")
	apiRoutes.GET("/users/:id", GetUser)
	apiRoutes.GET("/users/:id/email", GetUserByEmail)

Basically, both routes need to have the wildcard in the same position, and the wildcards need to be named the same thing.

@davexpro
Copy link

Understood, thank you.

However, I was fiddling with this more today and found a workaround that I wanted to share here in case anyone else comes across this issue.

If I change my routes to look like this, everything works fine:

        apiRoutes := r.Engine.Group("/api")
	apiRoutes.GET("/users/:id", GetUser)
	apiRoutes.GET("/users/:id/email", GetUserByEmail)

Basically, both routes need to have the wildcard in the same position, and the wildcards need to be named the same thing.

Do you have some good alternatives?

I encounter the same problem...

@thinkerou
Copy link
Member

why not change name? like:

apiRoutes := r.Engine.Group("/api/users")
apiRoutes.GET("/byid/:id", GetUser)
apiRoutes.GET("/byemail/:id", GetUserByEmail)

@djumpen
Copy link

djumpen commented Jan 30, 2019

I needed such routes:

POST /users
GET /users/:id
GET /users/:id/status
POST /users/actions/some-action // panic

I have to switch to the next model:

POST /users
GET /users/user/:id
GET /users/user/:id/status
POST /users/actions/some-action

@vchakoshy
Copy link

Router:

r.GET("/auth/user/:id/", badUserSearchHandler)
// r.GET("/auth/user/search/", badUserSearchHandler)

bad Function

func badUserSearchHandler(c *gin.Context) {
	id := c.Param("id")
	if id == "search" {
		searchUser(c)
		return
	}
	userItem(c)
}
func searchUser(c *gin.Context) {
	qInput := strings.TrimSpace(c.Query("q"))
        .....
}
func userItem(c *gin.Context) {
	id := c.Param("id")
        ....
}

@kuchaguangjie
Copy link

kuchaguangjie commented Apr 7, 2021

Any solution yet?
GET /:id and GET /count conflict, it's a very common requirement,

@Andro999b
Copy link

Why this closed? GIN route matching is super ugly.

okpalaChidiebere added a commit to okpalaChidiebere/udagram-restapi-golang that referenced this issue May 19, 2021
We generated a Presigned Url for PUT and GET

PUT Presigned url will be used to make a put request to upload an image to our S3 bucket

GET presinged url will be used to load an image

Both links expires after 5 mins

FYI: I did some code refactoring in for our multiplexer. Route matching with the julienschmidt multiplexer was so bad!
gin-gonic/gin#1301
@pavelpatrin
Copy link

There was a PR to improve httprouter used by gin: julienschmidt/httprouter#329.
Maybe we can ask @rw-access and @julienschmidt there to go forward with it.
Maybe start some crowdfunding to get it released?

@pavelpatrin
Copy link

Guys?

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