CSDN 中文章不一定能及时更新,欢迎关注我的博客查看最新版本:许盛的博客
背景
如何让后端同学愉快地写接口文档,是个老大难问题。
使用 GraphQL
当接口标准,倒是省了接口文档的问题,连前端代码都可以自动生成了,但是对后端同学来说,学习成本又比较大。
使用 gRPC
当接口标准,后端同学是爽了,但是前端的 gPRC
相关生态和工具是真的烂,体验极差。
有段时间尝试搞了个前端 BFF
层,把 gPRC
接口转换为 GraphQL
接口供前端调用,听起来很美好,但是却额外多了一个需要维护的项目,工作量陡增,接口出现问题时排查也变麻烦了。
后来还是选择在 yapi
接口平台上人工维护接口文档,每次改了接口,都要上去点点点,也挺麻烦的。
目前来说,主流的接口描述方法, Swagger(OpenAPI)
肯定是首当其冲了,曾经尝试了下手写 OpenAPI 的 yaml 文件,来生成接口文档,功能倒是挺强大的,但是密密麻麻的 yaml
文件,维护起来要吐血了。
nest.js
中可以用装饰器语法来自动生成 swagger 文档,基本可以满足常见的所有需求,但是需要写大量的装饰器,对业务代码的简洁性会带来一定的影响,时间用长了也挺烦的。
最近正好梳理了一下 go
的编码规范,在 go
中用注释的方式来自动生成 swagger 文档,功能还比较全面,而且全都是注释,也不会对阅读代码带来太多的干扰,相对来说还比较能接受。
介绍
不管是 gin
还是 iris
框架,都支持通过注释的方式来生成 swagger 文档。
同时注释中,还可以直接引用 go 代码中声明的 struct
,通过 struct tag
来针对字段进行具体的描述,相当方便。
这里我使用 iris
为例。
安装
先安装相关依赖
go get -u github.com/swaggo/swag/cmd/swag
go get github.com/iris-contrib/swagger/v12@master
然后在项目目录下执行 swag init
命令,生成相关的 yaml
和 html
文件。
配置
下面是官方仓库使用的一段示例代码:
package main
import (
"github.com/kataras/iris/v12"
"github.com/iris-contrib/swagger/v12"
"github.com/iris-contrib/swagger/v12/swaggerFiles"
_ "github.com/your_username/your_project/docs"
// docs folder should be generated by Swag CLI (swag init),
// you have to import it.
)
// @title Swagger Example API
// @version 1.0
// @description This is a sample server Petstore server.
// @termsOfService http://swagger.io/terms/
// @contact.name API Support
// @contact.url http://www.swagger.io/support
// @contact.email support@swagger.io
// @license.name Apache 2.0
// @license.url http://www.apache.org/licenses/LICENSE-2.0.html
// @host localhost:8080
// @BasePath /v2
func main() {
app := iris.New()
config := swagger.Config{
// The url pointing to API definition.
URL: "http://localhost:8080/swagger/doc.json",
DeepLinking: true,
DocExpansion: "list",
DomID: "#swagger-ui",
// The UI prefix URL (see route).
Prefix: "/swagger",
}
swaggerUI := swagger.Handler(swaggerFiles.Handler, config)
// Register on http://localhost:8080/swagger
app.Get("/swagger", swaggerUI)
// And the wildcard one for index.html, *.js, *.css and e.t.c.
app.Get("/swagger/{any:path}", swaggerUI)
app.Listen(":8080")
}
注意不要漏掉了 import 里的几行代码
上面的例子可以看出来,使用还是非常简单的,除了 swagger
的基础配置以及页面的渲染代码,其他的声明都在注释中,对业务代码的侵入性非常小,注释一折叠,就不影响阅读了。
使用
上面介绍了全局的引入和配置,那么如何具体的定义一个接口呢?
对于一个接口来说,主要包含了一下几个概念:
- summary: 概述
- description: 描述
- accept: 接收的数据类型
- produce: 返回的数据类型
- tags: 接口的标签(用来在 swagger ui 页面中分组显示)
- param:参数(描述参数在请求的哪一部分,数据类型,是否必填,描述等等)
- success:成功时返回的状态码,数据类型等
- router:接口路径、方法
// 创建新用户 godoc
// @summary 创建新用户
// @description 管理员创建新用户账号,可以指定用户角色和是否为管理员账户
// @accept json
// @produce json
// @tags admin
// @param name body string true "用户名,建议使用姓名拼音"
// @param nick_name body string true "用户昵称,请使用真实姓名"
// @param phone body string true "手机号"
// @param email body string true "邮箱"
// @param password body string true "密码"
// @param role body string true "用户角色,student 学生或 teacher 老师" Enums(student, teacher)
// @param is_admin body bool true "是否是管理员"
// @success 200 {object} swagger.Resp{data=model.User}
// @router /api/v1/admin/create-user [post]
func (a Admin) CreateUser(c iris.Context) {
}
以上面的代码为例,只要在注释中,描述清楚所有的相关概念,一个接口就声明好了。
再次执行swag init
命令,会根据当前项目中的所有注释,生成新的接口描述文件。
然后将项目运行起来,访问 http://localhost:8080/swagger/index.html 即可打开 swagger 文档页面。
每行注释中各个单词表示什么意思,可以在这个链接中查看详情:
https://github.com/swaggo/swag/blob/master/README_zh-CN.md#通用api信息