0

我有两个 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/。此错误是预期行为还是我的配置文件有任何问题?

4

2 回答 2

4

这是 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}
于 2020-04-15T15:20:19.740 回答
1

感谢@alo 解释这个问题。

我遇到了同样的问题,因为我有以下方式的 krakend 端点:

GET: /v1/projects/{project_uuid}

GET: /v1/projects/{project_key}/portfolio

但令人惊讶的是,像这样欺骗 krakenD 效果很好。

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

现在这个端点按预期触发我的后端客户端。希望这个烦人的事情得到解决。

于 2021-08-25T02:04:14.403 回答