【问题标题】:How to get Swagger UI to display similar Spring Boot REST endpoints?如何让 Swagger UI 显示类似的 Spring Boot REST 端点?
【发布时间】:2019-01-22 13:50:50
【问题描述】:

我有一个带有两个端点的控制器类

@RestController
@RequestMapping
public class TestController {

  @RequestMapping(
          value= "/test",
          method = RequestMethod.GET)
  @ResponseBody
  public String getTest() {
    return "test without params";
  }

  @RequestMapping(
          value= "/test",
          params = {"param"},
          method = RequestMethod.GET)
  @ResponseBody
  public String getTest(@PathParam("param") int param) {
    return "test with param";
  }

}

一个有参数,一个没有,两者都起作用。

如果我使用 curl 或 Web 浏览器来访问端点

http://localhost:8081/test

返回

无参数测试

http://localhost:8081/test?param=1

返回

用参数测试

但是swagger ui只显示没有参数的那个。

如果我将带有参数的请求的请求映射中的值更改为

  @RequestMapping(
          value= "/testbyparam",
          params = {"param"},
          method = RequestMethod.GET)

Swagger UI 正确显示两个端点,但我不希望根据 swagger 将显示或不显示什么来定义我的端点。

我有什么方法可以让 swagger ui 正确显示具有匹配值但参数不同的端点?

编辑澄清:

端点工作得很好; /test 和 /test?param=1 都可以正常工作,问题是 swagger-ui 不会显示它们。

我希望 swagger ui 显示我定义的端点,但如果不能,那么我将不得不忍受 swagger-ui 缺少我的一些端点。

参考编辑:

这里回答的人:Proper REST formatted URL with date ranges

明确表示不要用斜杠分隔查询字符串

他们还说“查询字符串之前不应该有斜线。”

【问题讨论】:

  • 虽然 Spring 可以处理这两个请求映射,但 Swagger 仍然认为它们不明确,并且只会显示它们。如果我没记错的话,Spring 最近才能够处理这些问题(但我使用了各种各样的 spring 版本,所以我可能是错的。)
  • 等等,很抱歉,你能澄清一下你想要什么。您是否期待 QUERY PARAMS(您声明)或 PATH PARAMS(您已编码)查询参数:GET /test 和 GET /test?param=1 路径参数:GET /test 和 GET /test/1
  • 我想我可能误解了两者的区别,但听起来我想要路径参数。我编码的就是我想要的;我拥有的端点是我想要保留的端点。如果冷冻豌豆的罗迪是正确的,并且这是 Swagger 当前的限制,那么我将坚持当前的路径变量,不再担心 Swagger。
  • URL 路径中显示路径参数:/test/123 查询字符串中显示查询参数:/test?param=123。您在上面提供的代码使用@PathParam,这是一个路径参数,但您的描述是指查询参数(将使用@RequestParam。请说明您期望的行为
  • 这很重要,因为您尝试做的事情可以使用路径参数,/test/test/123 是不同的路由,但不是使用查询参数,尽管有比什么更干净的方法来做它们你有上面。

标签: spring spring-boot swagger


【解决方案1】:

在阅读澄清后,这里的问题是 swagger-ui 正在做正确的事情。

您有两个控制器端点,但它们用于相同的 RESOURCE /test,它采用一组可选的查询参数。

实际上,所有具有相同方法 (GET) 和请求映射 (/test) 的映射控制器端点都代表一个单一的逻辑资源。 test 资源上的 GET 操作,以及一组可能影响调用该操作的结果的可选参数。

您已将其实现为两个独立的控制器端点这一事实是一个实现细节,并不会改变可以操作单个 /test 资源这一事实。

通过在 swagger UI 中将其列为两个单独的端点而不是带有可选参数的单个端点,这对 API 的使用者有什么好处?也许它可以限制允许的有效查询参数集(如果您设置?foo,则必须设置&bar)但这也可以在描述性文本中完成,并且是一种更标准的方法。就个人而言,我不熟悉任何公开记录的 api,这些 api 可以区分由查询参数区分的同一资源的多个操作。

【讨论】:

    【解决方案2】:

    我不清楚你到底想做什么,但我会给出两个解决方案:

    如果你想有 PATH 参数,例如GET /test & GET /test/123 你可以这样做:

      @GetMapping("/test")
      public String getTest() {
        return "test without params";
      }
    
      @GetMapping("test/{param}")
      public String getTest(@PathVariable("param") int param) {
        return "test with param";
      }
    

    如果您需要查询参数(GET /testGET /test?param=123),那么您需要一个带有可选参数的端点:

      @GetMapping("test")
      public String getTest(@RequestParam("param") Integer param) {
        if(param == null) { 
          return "test without params";
        } else {
          return "test with param";
        }
      }
    

    【讨论】:

    • 还有另一个注意事项:您使用的是@RestController,因此无需使用@RequestMapping 注释您的类,也无需使用@ResponseBody 注释您的方法
    • 感谢您提供有关删除 unnexxessary 注释的建议,减少杂乱是好的。我的端点按原样工作得很好;问题是招摇不认他们,但如果我不得不招摇,我可以。我试图在这里遵循stackoverflow.com/questions/9637297/… 的建议,答案说不要用斜杠分割查询字符串。
    • 在这种情况下,您的查询参数将没有斜杠,您将 PATH 参数与斜杠分开,而不是您的 QUERY 参数。我的假设是,无论您使用什么来生成招摇,都无法识别原始问题中的两种方法代表端点的不同风格,因为它们中的路径完全相同。
    • 那里的两个答案都说同样的事情“查询字符串之前不应该有斜杠。”他们是错的,还是不适用于我的情况。在我的实际代码中,除了两个端点之外,我还有更多可能的查询,一个是 id,另一个是我链接的问题中的日期范围。
    • GetMapping 似乎不像你建议的那样工作; swagger-ui 为它构建了这个 Curl 命令。 curl -X GET --header 'Content-Type: application/json' --header 'Accept: text/plain' -d '1234' 'localhost:8081/test/{param}'
    【解决方案3】:

    问题出在您的请求映射中,第二个方法声明覆盖了第一个方法。因为资源映射值是一样的。

    尝试将第二种方法更改为以下。由于您想在 QueryParam 而不是路径变量中提供输入,因此您应该使用 @RequestParam 而不是 @PathParam。

    注意你必须给/test/,为了告诉Spring你的映射没有歧义。希望对您有所帮助。

    @RequestMapping(
              value= "/test/",
              method = RequestMethod.GET)
      @ResponseBody
      public String getTest (@RequestParam("param") int param) {
        return "test with param"+param;
      }
    

    【讨论】:

    • 这不是我想要的映射。
    • 按回车太快了,我会在下面完成。
    • 现在 /test 和 /test?param=1 的端点都可以工作,问题是 swagger-ui 没有同时显示它们。我不想要端点 /test/param= 实际上,这里还有其他 REST 问题,答案不是像那样拆分参数。
    • stackoverflow.com/questions/9637297/… 回复的人说不要用斜杠分隔查询字符串
    • Damien ,我已经按照你的要求做了修改,这就是全部的目的,你可以有这样的要求localhost:8080/product/test/?param=1
    【解决方案4】:

    尝试在路径中包含参数,如下所示。

    @GetMapping("/test/{param}")
    public String getTest(@PathVariable final int param) {
        return "test with param";
    }
    

    【讨论】:

    • 我工作的端点;问题是 swagger ui 并没有全部识别出来。我试图遵循stackoverflow.com/questions/9637297/… 的建议,在那里回答的人说不要像你正在做的那样用斜杠分割查询字符串。
    • 您是否尝试过进行此更改并再次验证了 swagger ui? Swagger 应将其显示为两个不同的端点 - /test、/test/{param}。顺便说一句,param 是路径变量,而不是查询参数。
    • 顺便说一句,如果差异仅在查询参数中,则 Swagger UI 将 URL 分组到一个端点下是正确的。考虑一个用于管理用户的 api 示例,/users 是一个端点,您可以使用它来列出所有用户,并且可以应用不同的查询参数来过滤它(例如名称)。在这种情况下,可能会有多个结果,因此返回值将是集合。但是,如果您想使用唯一 id 查找用户,则使用路径参数 /users/{id} 中的 id,它将只返回一个结果。 Swagger UI 会将这些端点显示为 /users 和 /users/{id}。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-23
    • 1970-01-01
    • 2022-08-17
    相关资源
    最近更新 更多