【问题标题】:krakend api gateway panic: "X in new path conflicts with existing wildcard Y in existing prefix Z"krakend api 网关恐慌:“新路径中的 X 与现有前缀 Z 中的现有通配符 Y 冲突”
【发布时间】:2020-07-28 06:02:36
【问题描述】:

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

【问题讨论】:

    标签: api-gateway krakend


    【解决方案1】:

    这是 KrakenD 内部使用的 Gin library 的已知限制,您可以使用此 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",
        })
    }
    

    查看this issue中的代码。

    解决方案是声明不与其他端点的子集发生冲突的端点路径。在您的配置中,端点/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}
    

    【讨论】:

      【解决方案2】:

      感谢 @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
      

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

      【讨论】:

        猜你喜欢
        • 2020-03-27
        • 2016-07-21
        • 2019-03-21
        • 2020-10-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-11-25
        • 1970-01-01
        相关资源
        最近更新 更多