I have two webservices, and I'd like to manage both endpoints separated by the prefix using krakend API gateway.
Below is my configuration:
{
"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"
]
}
]
}
]
}
when I run it, error occurs:
panic: 'member' in new path '/api/entity/member/assign/:userID' conflicts with existing wildcard ':entityID' in existing prefix '/api/entity/:entityID'
As far as I understand, it seems the {entityID}
on the first endpoint is conflicting with /member/
in the second endpoint. Is this error expected behaviour or is there any problem with my configuration file?
This is a known limitation of the Gin library that KrakenD uses internally, you can reproduce this behavior directly in the library with this go code, which will reproduce exactly the same issue:
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",
})
}
See the code in this issue.
The solution is to declare endpoint paths that are not colliding subsets of other endpoints. In your configuration the endpoint /api/entity/member/assign/{userID}
is a subset of /api/entity/{entityID}
.
Notice that {placeholders}
are like using wildcards, so your first endpoint could be expressed in other systems like /api/entity/*
, and therefore /api/entity/member/assign/{userID}
is a positive match.
Any slight change in your configuration where the wildcard does not collide will fix this situation. As an example, the following two endpoints would work for you:
/api/entity/find/{entityID}
/api/entity/member/assign/{userID}