英文:
How to add different endpoints with the same path prefix and param in Gin?
问题
我使用Gin框架在Go中构建了一个API。我在API中有一个路由,可以通过id获取用户。但现在我还想通过他们的用户名获取用户。所以我尝试了与获取id用户相同的方式。但在编译过程中出现了错误。你能告诉我如何做吗?
谢谢。
路由 -
grp.GET("/users", controllers.GetUsers)
grp.GET("/users/:id", controllers.GetUser)
grp.GET("/users/:username", controllers.GetUserByUsername)   //error - panic: ':username' in new path '/users/:username' conflicts with existing wildcard ':id' in existing prefix '/users/:id'
grp.POST("/users", controllers.CreateUser)
grp.PATCH("/users/:id", controllers.UpdateUser)
grp.DELETE("/users/:id", controllers.DeleteUser)
控制器 -
func GetUser(c *gin.Context) {
    paramID := c.Params.ByName("id")
    ctx := context.Background()
    sa := option.WithCredentialsFile(firestoreFilePath)
    app, err := firebase.NewApp(ctx, nil, sa)
    if err != nil {
        log.Fatalln(err)
    }
    client, err := app.Firestore(ctx)
    if err != nil {
        log.Fatalln(err)
    }
    defer client.Close()
    dsnap, err := client.Collection("users").Doc(paramID).Get(ctx)
    if err != nil {
        fmt.Print(err)
        c.IndentedJSON(http.StatusNotFound, gin.H{
            "message": "User not found",
        })
        return
    }
    m := dsnap.Data()
    c.IndentedJSON(http.StatusNotFound, gin.H{
        "User":    m,
        "message": "User returned successfully",
    })
}
API响应 -
[
  {
     "id": 1,
     "name": "Leanne Graham",
     "username": "Bret",
     "email": "Sincere@april.biz",
  },
  {
    "id": 2,
    "name": "Ervin Howell",
    "username": "Antonette",
    "email": "Shanna@melissa.tv",
  },
  {
    "id": 3,
    "name": "Clementine Bauch",
    "username": "Samantha",
    "email": "Nathan@yesenia.net",
  }
]
英文:
I have built an API in Go using the Gin framework. I have one route in API where I can get users with id. But now I also want to get users by their username. So I tried the same way which I did for getting users with id. But it is giving me an error during compile. Can you guys please tell me how can I do that?
Thank you.
Routes -
grp.GET("/users", controllers.GetUsers)
grp.GET("/users/:id", controllers.GetUser)
grp.GET("/users/:username", controllers.GetUserByUsername)   //error - panic: ':username' in new path '/users/:username' conflicts with existing wildcard ':id' in existing prefix '/users/:id'
grp.POST("/users", controllers.CreateUser)
grp.PATCH("/users/:id", controllers.UpdateUser)
grp.DELETE("/users/:id", controllers.DeleteUser)
Controller -
func GetUser(c *gin.Context) {
	paramID := c.Params.ByName("id")
	ctx := context.Background()
	sa := option.WithCredentialsFile(firestoreFilePath)
	app, err := firebase.NewApp(ctx, nil, sa)
	if err != nil {
		log.Fatalln(err)
	}
	client, err := app.Firestore(ctx)
	if err != nil {
		log.Fatalln(err)
	}
	defer client.Close()
	dsnap, err := client.Collection("users").Doc(paramID).Get(ctx)
	if err != nil {
		fmt.Print(err)
		c.IndentedJSON(http.StatusNotFound, gin.H{
			"message": "User not found",
		})
		return
	}
	m := dsnap.Data()
	c.IndentedJSON(http.StatusNotFound, gin.H{
		"User":    m,
		"message": "User returned successfully",
	})
}
API response -
[
  {
     "id": 1,
     "name": "Leanne Graham",
     "username": "Bret",
     "email": "Sincere@april.biz",
  },
  {
    "id": 2,
    "name": "Ervin Howell",
    "username": "Antonette",
    "email": "Shanna@melissa.tv",
  },
  {
    "id": 3,
    "name": "Clementine Bauch",
    "username": "Samantha",
    "email": "Nathan@yesenia.net",
  }
]
</details>
# 答案1
**得分**: 1
这是gin中已知的限制。你需要使所有路径都唯一。可以像下面这样添加前缀:
    grp.GET("/users/username/:username", controllers.GetUserByUsername)
关于这个问题的更多信息,请参考以下链接:
https://github.com/gin-gonic/gin/issues/1301
<details>
<summary>英文:</summary>
This is a known limitation in gin. You'll have to make all paths unique. Like adding a prefix as below:
    grp.GET("/users/username/:username", controllers.GetUserByUsername)
There's more info on this issue thread:
https://github.com/gin-gonic/gin/issues/1301
</details>
				通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论