【问题标题】:How to expose swagger UI with http4k?如何使用 http4k 公开招摇的 UI?
【发布时间】:2020-05-11 11:54:48
【问题描述】:

我正在使用http4k framework 使用他们的Contract APIs 构建一个微服务。我可以轻松地在例如上公开 swagger API 描述 JSON。 /swagger.json

fun app(): HttpHandler = "/" bind contract {
    renderer = OpenApi3(ApiInfo("GoOut Locations API", "1.0"), Jackson)
    descriptionPath = "/swagger.json"
    routes += ...
}

有没有一种简单的方法来公开swagger UI,以便 1) 我可以指定它可用的路径。 (例如/swagger-ui) 2) UI 将被预先配置为从上面指定的descriptionPath 获取描述 JSON。

理想的 API 应该是这样的

fun app(): HttpHandler = "/" bind contract {
    renderer = OpenApi3(ApiInfo("GoOut Locations API", "1.0"), Jackson)
    descriptionPath = "/swagger.json"
    uiPath = "/swagger-ui"
    routes += ...
}

【问题讨论】:

    标签: kotlin swagger-ui http4k


    【解决方案1】:

    经过一番搜索,我结合Web Jars 和http4k 的静态路由实现了这一点。

    文档的潜在查看者必须简单地访问/docs 路径,在该路径中他会被重定向到/docs/index.html?url=<path to Api description> 位置

    • index.html 是从 Web jar 提供的静态 Swagger UI 入口点。
    • url 查询参数告诉 swagger UI 从哪里获取 OpenApi 描述。

    从 DX 的角度来看,我们有一个简单的 http4k 应用程序:

    // path the OpenApi description will be exposed on
    private const val API_DESCRIPTION_PATH = "/swagger.json"
    
    fun app(): HttpHandler {
        val api = contract {
            renderer = OpenApi3(ApiInfo("Your API summary", "1.0"), Jackson)
            descriptionPath = API_DESCRIPTION_PATH
            // the actual API routes
            routes += ... 
        }
    
         return routes(
             // the docs routes are not considered part of the API so we define them outside of the contract
             swaggerUi(API_DESCRIPTION_PATH),
             api
         )
    }
    

    swaggerUi 处理程序实现如下

    /**
     * Exposes Swagger UI with /docs path as its entry point.
     * @param descriptionPath absolute path to API description JSON. The UI will be configured to fetch it after load.
     */
    fun swaggerUi(descriptionPath: String): RoutingHttpHandler = routes(
        "docs" bind Method.GET to {
            Response(Status.FOUND).header("Location", "/docs/index.html?url=$descriptionPath")
        },
        // For some reason the static handler does not work without "/" path prefix.
        "/docs" bind static(Classpath("META-INF/resources/webjars/swagger-ui/3.25.2"))
    )
    

    我们还必须包含 swagger-ui webjar 作为我们的依赖项。这是一个 Gradle 指令:

    implementation 'org.webjars:swagger-ui:3.25.2'
    

    查看 webjars 网站了解 Maven(以及更多)指令。

    请注意,swaggerUi 处理程序假定它绑定到整个服务的 / 根路径。不过,这很容易解决。

    【讨论】:

      【解决方案2】:

      http4k 不附带 OpenApi UI 版本。您可以通过以下方式轻松发布 UI 版本:

      1. 将 OpenApi UI 解压到 src/main/resources/public 文件夹中
      2. 使用static 路由块为资源提供服务。这里有一个例子:https://github.com/http4k/http4k-by-example/blob/22dcc9a83c497253c29830d5bc981afa5fbbe4ff/src/main/kotlin/verysecuresystems/SecuritySystem.kt#L61

      【讨论】:

      • 非常感谢您的回答!与此同时,我已经解决了这个问题并在下面发布了解决方案。由于我的答案更完整,因此我计划将其标记为已接受的答案。 (一旦两个数据限制通过)希望,这对你来说没问题。 .)
      【解决方案3】:

      使用 webjar 的解决方案不再适用于 SwaggerUI 版本 >= 4.1.3,因为 url 参数被忽略(请参阅 this issue / the release notes)。必须在 HTML 中指定 URL,或者需要在 HTML 中启用 url 参数。 所以目前的解决方案似乎是解压 UI,更新 index.html,然后直接通过 webjar 提供服务。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-12-14
        • 1970-01-01
        • 2019-03-21
        • 1970-01-01
        • 1970-01-01
        • 2017-08-21
        • 2018-07-25
        • 2017-10-06
        相关资源
        最近更新 更多