我有两个Web服务,我想使用krakend API网关管理用前缀分隔的两个端点。
以下是我的配置:
{
"version": 2,
"name": "My API Gateway",
"port": 8080,
"host": [],
"endpoints": [
{
"endpoint": "/api/entity/{entityID}",
"output_encoding": "no-op",
"method": "POST",
"backend": [
{
"url_pattern": "/api/entity/{entityID}",
"encoding": "no-op",
"host": [
"http://987.654.32.1"
]
}
]
},
{
"endpoint": "/api/entity/member/assign/{userID}",
"output_encoding": "no-op",
"method": "GET",
"backend": [
{
"url_pattern": "/api/entity/member/assign/{userID}",
"encoding": "no-op",
"host": [
"http://123.456.789.0"
]
}
]
}
]
}
当我运行它时,出现错误:
panic: 'member' in new path '/api/entity/member/assign/:userID' conflicts with existing wildcard ':entityID' in existing prefix '/api/entity/:entityID'
据我所知,第一个端点上的{entityID}
似乎与第二个端点中的/member/
冲突。这是预期的错误行为,还是我的配置文件有任何问题?
这是KrakenD内部使用的Gin库的一个已知限制,您可以使用此go代码直接在库中重现这种行为,这将重现完全相同的问题:
package main
import "github.com/gin-gonic/gin"
func main() {
r := gin.New()
r.GET("/ping", handler)
r.GET("/ping/foo", handler)
r.GET("/ping/:a", handler)
r.GET("/ping/:a/bar", handler)
}
func handler(c *gin.Context) {
c.JSON(200, gin.H{
"message": "pong",
})
}
请参阅本期中的代码。
解决方案是声明不与其他端点的子集冲突的端点路径。在您的配置中,端点/api/entity/member/assign/{userID}
是/api/entity/{entityID}
的子集。
请注意,{placeholders}
类似于使用通配符,因此您的第一个端点可以在其他系统(如/api/entity/*
(中表示,因此/api/entity/member/assign/{userID}
是正匹配。
配置中通配符不冲突的任何细微更改都会解决这种情况。例如,以下两个端点将适用于您:
/api/entity/find/{entityID}
/api/entity/member/assign/{userID}
感谢@alo对此问题的解释。
我遇到了同样的一个,因为我有以下方式的krakend端点:
GET: /v1/projects/{project_uuid}
GET: /v1/projects/{project_key}/portfolio
但令人惊讶的是,通过这样欺骗克拉肯D效果很好。
GET: /v1/projects/{key} // In swagger docs mentioned this key to be supplied as uuid
GET: /v1/projects/{key}/portfolio // In swagger docs mentioned this key to be supplied as string
目前,这个端点按预期触发了我的后端客户端。希望这个烦人的事情能解决。