基本介绍

GoFrameServer默认自带的OpenAPI接口文档UI是redoc开源组件,该组件不支持页面Try It Out功能的。很多同学都在问,能否使用SwaggerUI页面来展示OpenAPI接口文档?有的企业内部并不支持连接外网的部分资源,那么能否将内部的接口文档UI替换为内部可访问的资源呢?

了解OpenAPI这个东东的小伙伴应该都知道,OpenAPI只是通用的接口定义规范,而展示的接口文档UI是可以随便替换的,并且这种UI界面以及平台还特别多!使用GoFrame Server来切换接口文档UI页面,或者将接口文档对接到第三方接口文档平台 - 非常简单!详见示例:gf/example/httpserver/swagger-set-template/main.go at master · gogf/gf (github.com)


使用示例

咱们通过代码来展示一下,如何快速地将接口文档UI切换为SwaggerUISwaggerUI的相关链接:

main.go

package main

import (
	"context"
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/net/ghttp"
)

// HelloReq hello request
type HelloReq struct {
	g.Meta `path:"/hello" method:"get" sort:"1"`
	Name   string `v:"required" dc:"Your name"`
}

// HelloRes hello response
type HelloRes struct {
	Reply string `dc:"Reply content"`
}

// Hello Controller
type Hello struct{}

// Say function
func (Hello) Say(ctx context.Context, req *HelloReq) (res *HelloRes, err error) {
	g.Log().Debugf(ctx, `receive say: %+v`, req)
	res = &HelloRes{
		Reply: fmt.Sprintf(`Hi %s`, req.Name),
	}
	return
}

const (
	MySwaggerUITemplate = `
<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="utf-8" />
	<meta name="viewport" content="width=device-width, initial-scale=1" />
	<meta name="description" content="SwaggerUI"/>
	<title>SwaggerUI</title>
	<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/swagger-ui/5.10.5/swagger-ui.min.css" />
</head>
<body>
<div id="swagger-ui"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/swagger-ui/5.10.5/swagger-ui-bundle.js" crossorigin></script>
<script>
	window.onload = () => {
		window.ui = SwaggerUIBundle({
			url:    '{SwaggerUIDocUrl}',
			dom_id: '#swagger-ui',
		});
	};
</script>
</body>
</html>
`
)

func main() {
	s := g.Server()
	s.Use(ghttp.MiddlewareHandlerResponse)
	s.Group("/", func(group *ghttp.RouterGroup) {
		group.Bind(
			new(Hello),
		)
	})
	s.SetSwaggerUITemplate(MySwaggerUITemplate)
	s.Run()
}

config.yaml

server:
  address:     ":8199"
  openapiPath: "/api.json"
  swaggerPath: "/swagger"


我们这里只定义了一个Hello的接口。可以看到,我们通过一个接口来展示SwaggerUIHTML页面,并且将OpenAPI的接口文件路径定义为/api.json,没有启用Server自带的UI页面。执行后,终端输出:

2022-05-18 20:41:09.160 [INFO] openapi specification is serving at address: http://127.0.0.1:8199/api.json
2022-05-18 20:41:09.161 [INFO] pid[57888]: http server started listening on [:8199]

  ADDRESS | METHOD |   ROUTE   |                             HANDLER                             |    MIDDLEWARE      
----------|--------|-----------|-----------------------------------------------------------------|--------------------
  :8199   | ALL    | /*        | github.com/gogf/gf/v2/net/ghttp.internalMiddlewareServerTracing | GLOBAL MIDDLEWARE  
----------|--------|-----------|-----------------------------------------------------------------|--------------------
  :8199   | ALL    | /api.json | github.com/gogf/gf/v2/net/ghttp.(*Server).openapiSpec           |                    
----------|--------|-----------|-----------------------------------------------------------------|--------------------
  :8199   | GET    | /hello    | main.(*Hello).Say                                               |                    
----------|--------|-----------|-----------------------------------------------------------------|--------------------
  :8199   | GET    | /swagger  | main.main.func1.1                                               |                    
----------|--------|-----------|-----------------------------------------------------------------|--------------------

戳此链接访问:http://127.0.0.1:8199/swagger/

页面展示如下:

开发者自定义其他的接口文档UI类似如此。

 常见UI模板

swagger-ui

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="utf-8" />
	<meta name="viewport" content="width=device-width, initial-scale=1" />
	<meta name="description" content="SwaggerUI"/>
	<title>SwaggerUI</title>
	<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/swagger-ui/5.10.5/swagger-ui.min.css" />
</head>
<body>
<div id="swagger-ui"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/swagger-ui/5.10.5/swagger-ui-bundle.js" crossorigin></script>
<script>
	window.onload = () => {
		window.ui = SwaggerUIBundle({
			url:    '{SwaggerUIDocUrl}',
			dom_id: '#swagger-ui',
		});
	};
</script>
</body>
</html>

openapi-ui

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>openAPI UI</title>
  </head>
  <body>
    <div id="openapi-ui-container" spec-url="{SwaggerUIDocUrl}" theme="light"></div>
    <script src="https://cdn.jsdelivr.net/npm/openapi-ui-dist@latest/lib/openapi-ui.umd.js"></script>
  </body>
</html>


Content Menu

  • No labels

7 Comments

  1. gf版本2.1.4用nginx反向代理时候swagger报错,不能自动调用二级目录,默认调用的/api.js到根域名下了。

    我的config.yaml配置如下:

    server:
      address: "0.0.0.0:8199"
      openapiPath: "/api.json"
      swaggerPath: "/swagger"


    请求swagger域名如下:https://www.banbantest.com/mytest/swagger

    正确的api.js应该是:https://www.banbantest.com/mytest/api.js,而我又找不到修改这个路径的地方

    报错如下:

    Something went wrong...

    Failed to load https://www.banbantest.com/api.json: 404 Not Found


    Stack trace

    Error: Failed to load https://www.banbantest.com/api.json: 404 Not Found
        at t.BaseResolver.<anonymous> (https://unpkg.com/redoc@2.0.0-rc.70/bundles/redoc.standalone.js:8:74881)
        at Generator.throw (<anonymous>)
        at s (https://unpkg.com/redoc@2.0.0-rc.70/bundles/redoc.standalone.js:8:72881)


    ReDoc Version: 2.0.0-rc.70
    Commit: 036f97d



    1. 反向代理自行修改相应的代理配置

  2. 我发现 api.json 会把所有 请求地址和 数据schemas 都在一个接口返回

    我不清楚这个是不是 openapi 的标准


    但会导致以下问题

    1、理论上 当项目越来越大,这个json 会很大,解析会比较难。

           改进建议,把schemas 不再同一个页面展示,而是通过ajax 按需加载

    2、tags 是放在path 下面的,不方便渲染页面 理论上应该 tag 下面同tag 的path

        



    1. 如果你看看如何改进就更好了,毕竟作者精力有限

    2. openapi就是这样的。

  3. 接入 token ,如何在 文档加入 全局 头部 传输token 

    现在生成的文档没有传递token 的地方 , 需要怎么加 ?

  4. 咱们通过代码来展示一下,如果快速地将接口文档UI切换为SwaggerUI

    中的“如果”

    应修改成

    “如何”。