前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >如何构建交互式的RESTful API文档

如何构建交互式的RESTful API文档

原创
作者头像
xiaojunzhou
修改2019-05-28 10:50:49
1.4K0
修改2019-05-28 10:50:49
举报
文章被收录于专栏:后台开发学习后台开发学习

0x00 背景

相信后端开发同学都写过API文档,如果你只开发API接口而不写文档会估计会被喷,而且写文档确实是个好习惯。但是写文档这个事确实挺痛苦的,之前我的做法是在内部开发人员内部约定一个markdown模板来填写,类似api.md这种格式,每个接口都会有多个字段(URL,Method,Params)来说明。

同时,再结合postman这种工具,在完成接口自测的同时,将自测过程中的json参数或query参数等信息写到上述文档中;在这个过程中需要自己构建参数以及相关字段的说明,比较的繁琐。所以,希望能有工具能自动将代码中的对象或注释信息生成API文档。本文接下来将介绍两个工具来解决上述中的问题:

Swagger

Swagger是一个简单但功能强大的API表达工具。它具有地球上最大的API工具生态系统,数以千计的开发人员,使用几乎所有的现代编程语言,都在支持和使用Swagger。使用Swagger生成API,我们可以得到交互式文档,自动生成代码的SDK以及API的发现特性等。

swaggo

swaggo是一个用于将golang注解自动转换为Swagger 2.0文档的工具。

从上面的介绍中可知,结合Swagger和swaggo这两个工具,我们可以做到:

  1. 自动生成API文档;
  2. 生成的文档是可交互的,甚至在文档页面上完成自测。

0x01 如何构建

本节内容将通过一个gin示例项目来演示如何使用swaggo来构建我们的API文档。为什么使用gin这个库?因为我们实际项目中使用的就是gin,比较熟悉哈。当然,swaggo支持多个web框架:

下面我们进入正题(如果你还不熟悉go环境、项目构建等相关知识点,请先阅读文档How to Write Go Code):

首先,请安装swag命令行工具:

代码语言:txt
复制
$ go get -u github.com/swaggo/swag/cmd/swag

创建一个gin示例项目,整个项目的结构如下图所示:

swag_demo_1.png
swag_demo_1.png

在示例项目会创建用户(user)的增删改查接口用于说明swaggo的使用方法; 其中,main.go代码如下所示:

代码语言:txt
复制
// @title swaggo demo
// @version 1.0
// @description swaggo demo

// @license.name Apache 2.0
// @license.url http://www.apache.org/licenses/LICENSE-2.0.html

// @host 127.0.0.1:8080
// @BasePath /api/v1
func main() {
	r := gin.Default()

	r.GET("api/v1/user/:id", handler.HandleGetUser)
	r.GET("api/v1/users", handler.HandleGetUsers)
	r.POST("api/v1/user", handler.HandlePostUser)
	r.PUT("api/v1/user", handler.HandlePutUser)
	r.DELETE("api/v1/user/:id", handler.HanleDeleteUser)

	if err := r.Run(); err != nil {
		fmt.Printf("Run err: %v", err)
	}
}

main函数上的注解会生成通用API信息(General API Info),其中@title,@version和@license.name是必须要填的,否则下面的步骤会失败;而@host@BasePath`这两个注解也非常重要,如果你想在文档页面测试你的接口的话;swaggo还支持其他很多General API Info 注解

然后,在main.go文件所在目录下执行命令swag init,执行命令后会在当前目前创建docs目录,其包含三个文件:

  • docs.go
  • swagger.json
  • swagger.yaml

其中,docs.go需要导入到main.go中,如下所示:

代码语言:txt
复制
import (
	"fmt"
	_ "github.com/chowxiaojun/go-demos/swaggo-demo/docs"
	"github.com/chowxiaojun/go-demos/swaggo-demo/handler"
	"github.com/gin-gonic/gin"
)

为什么要导入这个文件呢?我们可以看下docs.go这个文件:

代码语言:txt
复制
func init() {
	swag.Register(swag.Name, &s{})
}

如上代码所示,该文件中有一个init函数,该函数会在main函数之前执行,它的作用是注册了一个swagger,除此之外还有doc变量存储我们API的相关信息,后续在生成swagger UI形式的API文档页面时会需要用到。下面我们可以在main函数中再加一条路由:

r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))

运行main.go,在浏览器中输入地址http://127.0.0.1:8080/swagger/index.html。此时ginSwagger.WrapHandler就会去调用前面注册的swagger,生成下图中的页面,你会发现上面我们写的注解信息都已经显示在页面上了。

swag_demo_2.png
swag_demo_2.png

接下来我们来看下怎么生成一个API相关的信息,以HandleGetUserHandlePostUserAPI接口为例,详见user_handler.go和user.go这两个文件:

代码语言:txt
复制
// @Summary Get a User
// @Description get User by ID
// @Tags User
// @Produce  json
// @Param id path string true "User ID"
// @Success 200 {object} model.GetUserRsp
// @Failure 400 {object} model.GetUserRsp
// @Router /user/{id} [get]
func HandleGetUser(c *gin.Context) {
}

// @Summary Create a User
// @Description Create a User
// @Tags User
// @Accept json
// @Produce json
// @Param user body model.User true "User"
// @Success 200 {object} model.CommonRsp
// @Failure 400 {object} model.CommonRsp
// @Router /user [post]
func HandlePostUser(c *gin.Context) {
}
代码语言:txt
复制
type CommonRsp struct {
	ErrorCode int32  `json:"error_code" example:"0"`
	ErrorMsg  string `json:"error_msg" example:"success"`
}

type User struct {
	ID      string `json:"id" example:"10001"`
	Name    string `json:"name" example:"user name"`
	Address string `json:"address" example:"user address"`
}

type GetUserRsp struct {
	CommonRsp
	Users []User `json:"users"`
}

重新再目录下执行命令swag init,再次运行main.go,我们可以看到以下页面:

swag_demo_3.png
swag_demo_3.png

在上图中,已经标注了具体注解对应页面上的信息:

  • @Tags:设置接口标签,同一类接口可设置为一个标签
  • @Router:路由信息
  • @Param:参数标注支持多种类型,例如body,query,path等
  • @Success:失败的响应信息
  • @Failure:成功的响应信息
  • ...

上述图片中@Param是一个body参数,对应我们代码中定义的Model信息以及对应的JSON示例,再通过页面中的Try it out功能,我们可以直接在页面上调用我们的接口完成自测。swaggo还支持很多的API注解,请查看API Operation

0x02 结束语

本文通过一个实际的项目介绍了swagger和swaggo的概念和使用方式,大家应该有了一个初步的了解;如果大家感兴趣的话,可以在项目中进行实践。最后,再说下整个使用下来的感受:第一,它们确实解决了我们的痛点;第二,更重的是——在实践过程中学到如何设计一个好的RESTful API接口

除此之外,还需要注意一个问题:就是在生产环境中不能将这个文档暴露出去,这个可以通过很多方式来解决,在这里也不再赘述。

0x03 推荐阅读

下面是一些推荐阅读的链接,大家可以进一步进行阅读:

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 0x00 背景
  • 0x01 如何构建
  • 0x02 结束语
  • 0x03 推荐阅读
相关产品与服务
命令行工具
腾讯云命令行工具 TCCLI 是管理腾讯云资源的统一工具。使用腾讯云命令行工具,您可以快速调用腾讯云 API 来管理您的腾讯云资源。此外,您还可以基于腾讯云的命令行工具来做自动化和脚本处理,以更多样的方式进行组合和重用。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档