Go语言微服务框架 - 10.接口文档-openapiv2的在线文档方案

简介: 随着项目的迭代,一个服务会开放出越来越多的接口供第三方调用。虽然`protobuf`已经是通用性很广的IDL文件了,但对于未接触过这块的程序员来说,还是有很大的学习成本。在综合可读性和维护性之后,我个人比较倾向于使用oepnapiv2的方案,提供在线接口文档。

随着项目的迭代,一个服务会开放出越来越多的接口供第三方调用。

虽然protobuf已经是通用性很广的IDL文件了,但对于未接触过这块的程序员来说,还是有很大的学习成本。在综合可读性和维护性之后,我个人比较倾向于使用oepnapiv2的方案,提供在线接口文档。

接下来,我们一起来看看这部分的实现。

v0.7.0:接口文档-openapiv2的在线文档方案

项目链接 https://github.com/Junedayday/micro_web_service/tree/v0.7.0

目标

项目提供在线接口文档,供第三方快速地了解接口细节。

关键技术点

  1. 了解buf的openapiv2的插件
  2. 用swagger工具合并文档
  3. 利用swagger相关容器提供在线文档

swagger 是 openapiv2 的一种具体实现,在下文可等同于一个概念。

可以参考swagger官网了解详情:https://swagger.io/specification/v2/

目录构造

--- micro_web_service            项目目录
    |-- gen                            从idl文件夹中生成的文件,不可手动修改
       |-- idl                             对应idl文件夹
          |-- demo                             对应idl/demo服务,包括基础结构、HTTP接口、gRPC接口
            |-- order                            对应idl/order服务,同上
     |-- swagger.json                    新增:openapiv2的接口文档
    |-- idl                            原始的idl定义
       |-- demo                            业务package定义,protobuffer的原始定义
       |-- order                           业务order定义,同时干
    |-- internal                       项目的内部代码,不对外暴露
       |-- config                          配置相关的文件夹,viper的相关加载逻辑
       |-- dao                             Data Access Object层,是model层的实现
       |-- gormer                          从pkg/gormer中生成的相关代码,不允许更改
       |-- model                           model层,定义对象的接口方法,具体实现在dao层
       |-- mysql                           MySQL连接
       |-- server                          服务器的实现,对idl中定义服务的具体实现
       |-- service                         service层,作为领域实现的核心部分
     |-- zlog                            封装zap日志的代码实现
  |-- pkg                            开放给第三方的工具库
     |-- gormer                          gormer二进制工具,用于生成Gorm相关Dao层代码
    |-- buf.gen.yaml                   buf生成代码的定义,从v1beta升到v1
    |-- buf.yaml                       buf工具安装所需的工具,从v1beta升到v1
    |-- gen.sh                         生成代码的脚本:buf+gormer
    |-- go.mod                         Go Module文件
    |-- gormer.yaml                    将gormer中的参数移动到这里
    |-- main.go                        项目启动的main函数
    |-- swagger.sh                     新增:生成openapiv2的相关脚本

1.了解buf的openapiv2的插件

gRPC-Gateway的文档中,我们可以找到对应的buf插件使用方式:在buf.gen.yaml文件中,我们添加如下插件内容:

version: v1
plugins:
  - name: openapiv2
    out: gen/openapiv2

运行buf generate后,在gen/openapiv2目录下会根据我们在idl文件中的目录结构,生成多个接口文档。

2.用swagger工具合并文档

用buf标准的openapiv2插件会生成多份swagger文档,管理多个文件对使用方来说并不方便。最佳的使用体验,就是能将多个文档合并起来,用一个API文档统一交付。

这里,我们借助goswagger工具,合并文档。工具具体的安装方式可参考链接:https://goswagger.io/install.html。

安装后,运行如下命令,生成到文件 gen/swagger.json:

# 合并swagger文档
swagger mixin gen/openapiv2/idl/*/*.json -o gen/swagger.json
# 删除原始文档
rm -rf gen/openapiv2

3.利用swagger相关容器提供在线文档

在统一了swagger文件后,在线接口文档的实现方案有很多,例如swagger官网就可以提供简单的渲染。

这里,我用了个人比较常用的docker镜像redoc为例,搭建一个在线接口文档平台。

该镜像更多的使用方式可参考:https://hub.docker.com/r/redocly/redoc/

运行如下命令,即将swagger.json加载到镜像中:

docker run --name swagger -it --rm -d -p 80:80 -v $(pwd)/gen/swagger.json:/usr/share/nginx/html/swagger.json -e SPEC_URL=swagger.json redocly/redoc

我们在本地打开浏览器,输入 http://127.0.0.1:80/ 就能看到文档。

扩展点 - 公共的文档服务器:

我们往往更希望把文档放在一个公共的服务器上,可以简单地利用这两个关键技术实现:

  1. https://hub.docker.com/r/redocly/redoc/ 中的watch方案,即watch某个目录下的文件,根据文件变化实时更新接口
  2. 利用scp命令,将本地swagger.json上传到远端服务器

更复杂点的方案,可以考虑结合git流程来实现。

总结

至此,我们实现了一个关键性的功能:代码即接口文档,保证了接口文档随着代码更新的实时性。

同时,希望大家能够认识到接口文档的价值,最好能做到接口文档即代码,也就是将相关程序的逻辑尽可能地通过接口文档表达清楚。哪怕前期接口文档问题很多,只要我们不断迭代,后续总能趋于稳定,降低维护接口的成本。

目录
相关文章
|
2天前
|
人工智能 Go 调度
掌握Go并发:Go语言并发编程深度解析
掌握Go并发:Go语言并发编程深度解析
|
6天前
|
数据采集 存储 Go
使用Go语言和chromedp库下载Instagram图片:简易指南
Go语言爬虫示例使用chromedp库下载Instagram图片,关键步骤包括设置代理IP、创建带代理的浏览器上下文及执行任务,如导航至用户页面、截图并存储图片。代码中新增`analyzeAndStoreImage`函数对图片进行分析和分类后存储。注意Instagram的反爬策略可能需要代码适时调整。
使用Go语言和chromedp库下载Instagram图片:简易指南
|
1天前
|
Go 开发者
Golang深入浅出之-Go语言上下文(context)包:处理取消与超时
【4月更文挑战第23天】Go语言的`context`包提供`Context`接口用于处理任务取消、超时和截止日期。通过传递`Context`对象,开发者能轻松实现复杂控制流。本文解析`context`包特性,讨论常见问题和解决方案,并给出代码示例。关键点包括:1) 确保将`Context`传递给所有相关任务;2) 根据需求选择适当的`Context`创建函数;3) 定期检查`Done()`通道以响应取消请求。正确使用`context`包能提升Go程序的控制流管理效率。
7 1
|
2天前
|
安全 Go 开发者
Golang深入浅出之-Go语言并发编程面试:Goroutine简介与创建
【4月更文挑战第22天】Go语言的Goroutine是其并发模型的核心,是一种轻量级线程,能低成本创建和销毁,支持并发和并行执行。创建Goroutine使用`go`关键字,如`go sayHello("Alice")`。常见问题包括忘记使用`go`关键字、不正确处理通道同步和关闭、以及Goroutine泄漏。解决方法包括确保使用`go`启动函数、在发送完数据后关闭通道、设置Goroutine退出条件。理解并掌握这些能帮助开发者编写高效、安全的并发程序。
13 1
|
2天前
|
SQL 关系型数据库 MySQL
Golang数据库编程详解 | 深入浅出Go语言原生数据库编程
Golang数据库编程详解 | 深入浅出Go语言原生数据库编程
|
3天前
|
Go 开发者
Golang深入浅出之-Go语言流程控制:if、switch、for循环详解
【4月更文挑战第21天】本文介绍了Go语言中的流程控制语句,包括`if`、`switch`和`for`循环。`if`语句支持简洁的语法和初始化语句,但需注意比较运算符的使用。`switch`语句提供多分支匹配,可省略`break`,同时支持不带表达式的形式。`for`循环有多种形式,如基本循环和`for-range`遍历,遍历时修改原集合可能导致未定义行为。理解并避免易错点能提高代码质量和稳定性。通过实践代码示例,可以更好地掌握Go语言的流程控制。
11 3
Golang深入浅出之-Go语言流程控制:if、switch、for循环详解
|
3天前
|
Go
Golang深入浅出之-Go语言函数基础:定义、调用与多返回值
【4月更文挑战第21天】Go语言函数是代码组织的基本单元,用于封装可重用逻辑。本文介绍了函数定义(包括基本形式、命名、参数列表和多返回值)、调用以及匿名函数与闭包。在函数定义时,注意参数命名和注释,避免参数顺序混淆。在调用时,要检查并处理多返回值中的错误。理解闭包原理,小心处理外部变量引用,以提升代码质量和可维护性。通过实践和示例,能更好地掌握Go语言函数。
18 1
Golang深入浅出之-Go语言函数基础:定义、调用与多返回值
|
4天前
|
程序员 Go API
【Go语言快速上手(二)】 分支与循环&函数讲解
【Go语言快速上手(二)】 分支与循环&函数讲解
|
4天前
|
Go
Golang深入浅出之-Go语言基础语法:变量声明与赋值
【4月更文挑战第20天】本文介绍了Go语言中变量声明与赋值的基础知识,包括使用`var`关键字和简短声明`:=`的方式,以及多变量声明与赋值。强调了变量作用域、遮蔽、初始化与零值的重要性,并提醒读者注意类型推断时的一致性。了解这些概念有助于避免常见错误,提高编程技能和面试表现。
19 0
|
4天前
|
编译器 Go 开发者
Go语言入门|包、关键字和标识符
Go语言入门|包、关键字和标识符
22 0