Edited at

GoのフレームワークGinのルーティングで conflicts with existing wildcard が出る時の対処法

ginのルーティングでのワイルドカードの話。


生じた問題

以下のようなパスの場合

g := r.Engine.Group("v1")

g.GET("/threads", c.ListThreads)
g.GET("/threads/:id", c.GetThread)
g.POST("/threads", c.CreateThread)
g.PUT("/threads/:id", c.UpdateThread)
g.DELETE("/threads/:id", c.DeleteThread)

g.GET("/threads/:threadId/comments", c.ListComments)
g.GET("/threads/:threadId/comments/:id", c.GetComment)
g.POST("/threads/:threadId/comments", c.CreateComment)
g.PUT("/threads/:threadId/comments/:id", c.UpdateComment)
g.DELETE("/threads/:threadId/comments/:id", c.DeleteComment)

以下のようなエラーが出る。

panic: path segment ':id' conflicts with existing wildcard ':threadId' in path '/v1/threads/:id'


エラーが生じた原因

調べていると、ginのissueで同じようなエラーに直面している人が質問をしていて、エラーが生じる原因と解消法の1つが紹介されていた。


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


引用元: ginのissue

意訳すると

両方のルートは同じ位置にワイルドカードを持っている必要があり、ワイルドカードには、同じ名前をつける必要がある。

従って、先ほど記した以下のエラーが生じたのは、同じ位置に別の名前のワイルドカードが存在したため。

panic: path segment ':id' conflicts with existing wildcard ':threadId' in path '/v1/threads/:id'


解消する方法

ginのissueを参考にして以下のように同じ位置のワイルドカードを同じ名前にしてあげれば、エラーは解消される。


g := r.Engine.Group("v1")

g.GET("/threads", c.ListThreads)
g.GET("/threads/:threadId", c.GetThread)
g.POST("/threads", c.CreateThread)
g.PUT("/threads/:threadId", c.UpdateThread)
g.DELETE("/threads/:threadId", c.DeleteThread)

g.GET("/threads/:threadId/comments", c.ListComments)
g.GET("/threads/:threadId/comments/:id", c.GetComment)
g.POST("/threads/:threadId/comments", c.CreateComment)
g.PUT("/threads/:threadId/comments/:id", c.UpdateComment)
g.DELETE("/threads/:threadId/comments/:id", c.DeleteComment)


参考にさせていただいたサイト

gin/segment conflicts with existing wildcard #1301