swag生成接口文档步骤

512 阅读1分钟

Swag能够将Go的注释转换为Swagger2.0文档(访问github)。

使用介绍

在与Gin集成时,主要分成以下步骤:

  1. 设置swagger访问路径:
import (
	"github.com/gin-gonic/gin"
	swaggerFiles "github.com/swaggo/files"
	ginSwagger "github.com/swaggo/gin-swagger"
  
  "./docs"
)
func main() {
    r := gin.Default()
    r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
    //...
}
  1. 在接口代码中添加API操作注释。
  2. 执行命令swag init,在docs目录下生成docs.go等文件,启动后即可通过http://ip:port/swagger/swagger.html访问

生成接口文档过程

  1. swag init命令生成的docs.go,其内容包含json格式的接口元数据,启动时会被注册到swagger
func init() {
	swag.Register(SwaggerInfo.InstanceName(), SwaggerInfo)
}
  1. 同样是启动时,swag会将css、js这些固定的文件通过memFS放到内存中。
  • github.com/swaggo/files/ab0x.go中通过NewMemFS新建memFS
var (
	// FS is a virtual memory file system
	FS = webdav.NewMemFS()
)
  • 在其他文件github.com/swaggo/files/b0xfile__xxx.go将具体内容写到内存中。
func init() {
	f, err := FS.OpenFile(CTX, "/xxx", os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0777)
	// ...
}
  1. 浏览器访问http://ip:port/swagger/index.html时返回index.html。

github.com/swaggo/gin-swagger/swagger.go文件中,CustomWrapHandler解析访问路径为index.html时,使用html/template的能力将html内容返回给浏览器。

// CustomWrapHandler wraps `http.Handler` into `gin.HandlerFunc`
func CustomWrapHandler(config *Config, h *webdav.Handler) gin.HandlerFunc {
	//create a template with name
	t := template.New("swagger_index.html")
	index, _ := t.Parse(swagger_index_templ)
  
	return func(c *gin.Context) {
    // ...
		switch path {
		case "index.html":
			index.Execute(c.Writer, &swaggerUIBundle{
				URL: config.URL,
			})
		// ...
		}
	}
}
  1. 浏览器获取index.html内容后,自动加载其css、js等资源文件,而doc.json则是在js代码中请求的。

同样在github.com/swaggo/gin-swagger/swagger.go文件的CustomWrapHandler方法中,程序通过swag.ReadDoc()返回doc.json,通过h.ServeHTTP(c.Writer, c.Request)memFS中获取其他文件内容。

func CustomWrapHandler(config *Config, h *webdav.Handler) gin.HandlerFunc {
  // ...
	return func(c *gin.Context) {
    // ...
		switch path {
    // ...
		case "doc.json":
			doc, err := swag.ReadDoc()
			if err != nil {
				panic(err)
			}
			c.Writer.Write([]byte(doc))
			return
		default:
			h.ServeHTTP(c.Writer, c.Request)
		}
	}
}