概述

使用 Swagger 解决什么问题, 怎么使用 Swagger, 如何规范 go-swagger 的使用.

背景介绍

为了解决与后端对数据的的强耦合,  使用 HTTP 接口进行解耦.

而 Swagger 一方面可以非常友好的对外展示接口, 文档即接口, 另

一方面可以使用 go-swagger 自动生成部分 server 端代码, 快速实现接口开发. 方便以后可以快速开发 HTTP 服务接口

主要内容

简介

Swagger 是一个简单但功能强大的 API 表达工具。

Swagger 使用 OpenAPI 规范(试图通过定义一种用来描述API格式或API定义的语言,来规范RESTful服务开发过程).

使用 Swagger 生成 API,我们可以得到交互式文档,自动生成代码的 SDK 以及 API 的发现特性等。

wagger 主要包括三部分 Swagger API Spec,描述 Rest API 的语言。Swagger UI,将 Swagger API Spec 以 HTML 页面展现出来的模块。Swagger Editor,Swagger API Spec 的编辑器

为什么使用 swagger

主要是因为工作的核心在实时服务方面.

一方面: swagger能够帮助我们节省编写接口文档的时间,提高我们开发时的效率.

另一方面: 保证文档的即时性,准确性以及一致性, 减少不必要的沟通工作, 文档都是同一份

另外一方面: 使用 go-swagger 自动生成部分代码, 减少写重复代码.

go-swagger 简介

go-swagger 是 Swagger 2.0 的 Go 语言实现。将 swagger 接口文档生成客户端、服务端代码

怎么使用 Swagger

使用步骤

  1. 使用 swagger-editor 定义 API
  2. 使用 swagger-ui 展示 API 定义
  3. 使用 go-swagger 生成代码
  4. 基于代码增加业务处理逻辑

swagger-spec

Swagger 使用 OpenAPI 规范开发 API。后来, SmartBear Software 将 Swagger 规范捐赠给 Linux Foundation,并将规范重命名为OpenAPI规范。 SmartBear 成为OpenAPI Initiative(OAI)的创始成员,该机构以开放和透明的方式管理 OAS 的发展。

简而言之 Swagger 包含了一套 API 规范,并且提供一系列的生态组件
OpenAPI = 规范
Swagger = 实现规范的组件

swagger-ui

除官方提供的 swagger-ui 外, 还有一个Re-Doc, 界面交互我觉得更好一点, 但是存在一点的规范丢失.

go-swagger 生成服务端、客户端代码

swagger generate server --target  --name --spec ../../swagger.yaml

swagger generate client -f  swagger.yml -A  应用名称 -t 目录

如何自定义 handler

可以在生成代码的restapi.configure_*中手动将handler 的业务逻辑实现, 缺点是对生成的代码有修改, 约束性较高.

参考 kv-store (官方推荐), 每一个 handler 都定义一个 struct.

举例说明

接口列表

重新生成回放

批量查询重新生成回放状态

查询所有在线教师, 包括正在上课的老师以及在线的老师

批量查询连线信息

批量查询回放信息

定时同步session 信息

swagger 接口定义

swagger: '2.0'
info:description: '开放 API, 主要用于获取连线相关的信息'version: 1.0.0title: Swagger Sessioncontact:name: zhanghaojieemail: zhanghaojie@iyunxiao.com
externalDocs:description: Find out more about Swaggerurl: 'http://swagger.io'
basePath: /v1/session
tags:- name:  sessiondescription: '连线信息'
schemes:- http
host: testhfsfd-sessions.haofenshu.com
consumes:- application/json
produces:- application/json
paths:/playbackInfos:
    post:tags:- sessionsummary: '批量获取回放信息'description: '如果请求内容中包含不存在的连线 ID, 响应中不会包含此 ID 的任何信息'operationId: getPlaybackInfosBySessionIdsparameters:- name: sessionIdsdescription: '连线 ID 的数组'in: bodyrequired: trueschema:$ref: '#/definitions/SessionIds'responses:'201':description: '请求成功'schema:type: objectproperties:result:type: stringdescription: '结果情况, success 代表成功, 其他 代表失败'enum:- success- failexample:"success"msg:type: stringdescription: '对结果的描述'example:"获取成功"data:type: arrayitems:$ref: '#/definitions/PlaybackInfo''500':$ref: '#/responses/Standard500ErrorResponse'/{sessionId}/playbackStatus/regeneration:
    put:tags:- sessionsummary: '重新生成回放'description: '重新生成回放'operationId: setPlaybackStatusToRegenerationparameters:- name: sessionIddescription: '连线 ID'required: truein: pathtype: stringresponses:'201':description: '请求成功'schema:type: objectproperties:result:type: stringdescription: '结果情况, success 代表成功, 其他情况 代表失败'enum:- success- sessionNoFound- repeatSubmit- generatingexample:"success"msg:type: stringexample:"重新生成成功"'500':$ref: '#/responses/Standard500ErrorResponse'/playbackStatuses:
    post:tags:- sessionsummary: '批量获取回放状态信息'description: '如果请求内容中包含不存在的连线 ID, 响应中不会包含此 ID 的任何信息'operationId: getPlaybackStatusesBySessionIdsparameters:- name: sessionIdsdescription: '连线 ID 的数组'in: bodyschema:$ref: '#/definitions/SessionIds'responses:'201':description: '请求成功'schema:type: objectproperties:result:type: stringdescription: '结果情况, success 代表成功, 其他 代表失败'enum:- success- failexample:"success"msg:type: stringdescription: '对结果的描述'example:"获取成功"data:type: arrayitems:$ref: '#/definitions/PlaybackStatus''500':$ref: '#/responses/Standard500ErrorResponse'/teachers/{teacherStatus}:get:tags:- sessionsummary: '获取不同状态下所有的老师'operationId: getAllTeachersByStatusdescription: 'online 包含 inClass 中的老师'parameters:- name: teacherStatusdescription: 'online 表示在线的老师, inClass 表示连线中的老师'in: pathrequired: truetype: stringenum:- online- inClassresponses:'200':description: '请求成功'schema:type: objectproperties:result:type: stringdescription: '结果情况, success 代表成功, 其他 代表失败'enum:- success- failexample:"success"msg:type: stringdescription: '对结果的描述'example:"获取成功"data:type: arrayitems:type: string'500':$ref: '#/responses/Standard500ErrorResponse'/sessionInfosByRange:
    get:tags:- sessionsummary: '同步课堂信息, 通过传入 连线 开始时间的时间区间'operationId: getSessionInfosByRangeparameters:- name: startin: queryrequired: truedescription: '连线 开始时间的起始时间戳(unix 时间戳(毫秒))'type: integerformat: int64- name: endin: queryrequired: truedescription: '连线 开始时间的截止时间戳(unix 时间戳(毫秒))'type: integerformat: int64responses:'201':description: '请求成功'schema:type: objectproperties:result:type: stringdescription: '结果情况, success 代表成功, 其他 代表失败'enum:- success- failmsg:type: stringdescription: '对结果的描述'data:type: arrayitems:$ref: '#/definitions/SessionInfo''500':$ref: '#/responses/Standard500ErrorResponse'/sessionInfosBySessionIds:
    post:tags:- sessionsummary: '批量查询连线信息'description: '如果请求内容中包含不存在的连线 ID, 响应中不会包含此 ID 的任何信息'operationId: getSessionInfoBySessionIdsparameters:- name: sessionIdsdescription: SessionId's arrayin: bodyrequired: trueschema:$ref: '#/definitions/SessionIds'responses:'201':description: '请求成功'schema:type: objectproperties:result:type: stringdescription: '结果情况, success 代表成功, 其他 代表失败'enum:- success- failmsg:type: stringdescription: '对结果的描述'data:type: arrayitems:$ref: '#/definitions/SessionInfo''500':$ref: '#/responses/Standard500ErrorResponse'
definitions:PlaybackStatus:type: objectrequired:- sessionId- statusproperties:sessionId:type: stringdescription: '数据库 session 表中的 session 字段'example:"7210000"status:type: stringdescription: '回放状态信息: <br>playbackNotGenerated 回放还未生成, 包括需要重新生成, 还未生成 <br>sessionNotExist 课程不存在 <br>sessionNotFinish 课程正在上课 <br>playbackFailedGenerated 回放生成失败, 包括只有语音、只有画图等各种错误情况 <br>playbackSuccessGenerated 回放生成成功'default: sessionNotExistenum:- sessionNotExist- sessionNotFinish- playbackNotGenerated- playbackFailedGenerated- playbackSuccessGeneratedexample:"playbackSuccessGenerated"PlaybackInfo:type: objectrequired:- sessionIdproperties:sessionId:type: stringdescription: '回放视频 ID'example:"7210000"status:type: stringdescription: '回放状态信息: <br>sessionNotExist 课程不存在 <br>sessionNotFinish 课程正在上课 <br>playbackNotGenerated 回放还未生成, 包括需要重新生成, 还未生成 <br>playbackFailedGenerated 回放生成失败, 包括音频错误等各种错误情况 <br>playbackSuccessGenerated 回放生成成功, 存在下载地址, 视频大小 <br>playbackNotVideo 老回放, 只有视频地址 没有下载地址'default: sessionNotExistenum:- sessionNotExist- sessionNotFinish- playbackNotGenerated- playbackFailedGenerated- playbackSuccessGenerated- playbackNotVideoexample:"playbackSuccessGenerated"videoUrl:type: stringdescription: '新回放的下载地址'example:"http://yx-fudao.ks3-cn-beijing.ksyun.com/testreplayer_data/7210000/7210000.mp4?Expires=1548152332&AWSAccessKeyId=AKLT6GLT4mf1RoiAY5DCcsd_3Q&Signature=zXSJNkX9C3ovtmPYwF3Y2fNcXdY%3D"videoSize:type: integerformat: int64default: -1description: '新回放的文件大小(单位: byte)'example:1026323expire:type: integerformat: int64description: '新回放下载地址的过期时间(unix 时间戳(毫秒))'example:1548507047292webUrl:type: stringdescription: '旧回放的直接播放地址'example:"testhfsfd-replayer.haofenshu.com/entry?sid=7210000"SessionInfo:type: objectrequired:- sessionIdproperties:sessionId:type: stringdescription: '数据库 session 表中的 session 字段'example:"7210000"teacher:type: stringdescription: '老师的用户名'example:"muyi"student:type: stringdescription: '学生的用户名'example:"test014"status:type: stringdescription: '回放状态信息: <br>playbackNotGenerated 回放还未生成, 包括需要重新生成, 还未生成 <br>sessionNotExist 课程不存在 <br>sessionNotFinish 课程正在上课 <br>playbackFailedGenerated 回放生成失败, 包括只有语音、只有画图等各种错误情况 <br>playbackSuccessGenerated 回放生成成功'default: sessionNotExistenum:- sessionNotExist- sessionNotFinish- playbackNotGenerated- playbackFailedGenerated- playbackSuccessGeneratedexample:"playbackSuccessGenerated"classType:type: stringdescription: '课程类型, UnFormal 代表非正式课, Formal 代表正式课'enum:- UnFormal- Formalexample:"Formal"startTime:type: integerformat: int64description: '课程开始时间(unix 时间戳(毫秒))'example:1548085855endTime:type: integerformat: int64description: '课程结束时间(unix 时间戳(毫秒))'example:1548067573SessionIds:type: objectdescription: '连线 ID 的数组'required:- sessionIdsproperties:sessionIds:type: arrayuniqueItems: trueminItems: 1items:type: stringminLength: 1example:"7210000"example:["7210000","7210001","7210002","7210003","7210004","7210005"]Error:type: objectrequired:- messageproperties:message:type: stringexample:"database error"
responses:Standard500ErrorResponse:description: '服务器内部异常'schema:$ref: '#/definitions/Error'

接口定义规范

go-swagger 会做部分业务校验, 此时的返回码是RESTful风格 的HTTP Code

在 Swagger 中的描述性话语尽量使用中文. summary 使用简单概述, description 尽可能描述清楚

不必非得遵循 RESTful 风格. HTTP Method 仅使用 GET、POST、PUT 、DELETE 这些常用的方法, HTTP Code 也仅使用常用状态码

接口保证好的扩展性

个人思考

个人思考

为什么使用 Swagger

选用 Swagger 的主要考虑点在代码接口层跟接口文档的统一, 并且我们的主要工作并不是以写接口为主, 因此选用 Swagger 可以方便管理文档与兼顾效率.

Go 常用的 HTTP 框架如 Gin 与 Beego 都提供了对 Swagger 的支持, 但是需要将相应的注释或注解编写到方法上,再利用生成器自动生成说明Swagger文件. 他们将一些不是代码相关的内容注入到代码中, 增加部分冗余.

go-swagger、gin、beego 的区别

gin 在 Go 社区的流行度非常高, 远高于其他. 流行程度可以方便问题的处理. beego 在国内来说是使用的人数也不错, 但从论坛中看出大家开始放弃 Beego, 因为它的大而全. go-swagger 使用的人数还是相当较少, 从官方文档中看到使用go-swagger的一些项目中, 很多是使用它做 Client, 而非 Server.

go-swagger 的默认路由是 naoina's denco, 官方的文档中说明其是一个 ternary search tree, 相对于 gin 的 httprounter 中的 radix tree性能更好. (我也没有测试). beego 相关的路由实现我未找到, 其支持正则匹配.

go-swagger 对 handler 的管理

个人觉得这是一个很棘手的问题, 如果每个 handler 都写一个 struct 其实现其接口方法, 如果接口越来越多, 导致 main 方法中对 API 注入越来越多, 并且一个接口一个 struct 这种方式, 个人还是觉得非常不优雅的.大家有什么好的方法可以提供建议.

go-swagger 散失代码的灵活性

go-swagger 对 swagger spec 中的校验有实现, 可以说非常的方便, 减少业务代码的冗长. go-swagger 可以支持增加middleware, 进行一些功能扩展.

使用框架必然会散失部分灵活性, 这是一个权衡的问题.

总结

Swagger 结合 go-swagger 可以快速的开发 API 接口, 并且可以实现代码与接口文档的一致, 保证接口的一致. 结合当前项目还是非常棒的选择

参考资料

  1. Swagger Spec 结构
  2. 如何编写基于OpenAPI规范的API文档
  3. API接口管理之道
  4. Go HTTP路由基准测试

转载于:https://www.cnblogs.com/Zereker/p/11390850.html

Swagger 入门使用相关推荐

  1. Spring Boot API 接口文档 Swagger 入门

    转载自 芋道 Spring Boot API 接口文档 Swagger 入门 摘要: 原创出处 http://www.iocoder.cn/Spring-Boot/Swagger/ 「芋道源码」欢迎转 ...

  2. Swagger 入门

    Swagger 入门 1.首先引入pom坐标 <!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger-ui ...

  3. 芋道 Spring Boot API 接口文档 Swagger 入门

    点击上方"芋道源码",选择"设为星标" 做积极的人,而不是积极废人! 源码精品专栏 原创 | Java 2020 超神之路,很肝~ 中文详细注释的开源项目 RP ...

  4. Spring MVC学习总结(8)——Swagger入门详解

    前言 Swagger 是一款RESTFUL接口的文档在线自动生成+功能测试功能软件.本文简单介绍了在项目中集成swagger的方法和一些常见问题.如果想深入分析项目源码,了解更多内容,见参考资料. S ...

  5. swagger入门和实践(含docker部署swagger)

    全栈工程师开发手册 (作者:栾鹏) 架构系列文章 简介 Swagger 是最流行的 API 开发工具,它遵循 OpenAPI Specification(OpenAPI 规范,也简称 OAS). Sw ...

  6. swagger入门使用说明

    1:认识Swagger Swagger 是一个规范和完整的框架,用于生成.描述.调用和可视化 RESTful 风格的 Web 服务.总体目标是使客户端和文件系统作为服务器以同样的速度来更新.文件的方法 ...

  7. Spring Boot 2.x基础教程:Swagger静态API文档的生成

    点击蓝色"程序猿DD"关注我 回复"资源"获取独家整理的学习资料! 作者 | 翟永超 来源 | didispace.com/spring-boot-learni ...

  8. 使用SWAGGER和ASP.NET CORE设置可选路由参数

    使用SWAGGER和ASP.NET CORE设置可选路由参数 根据OpenAPI 3.0,这是不可能的.但是,如果您真的希望成为现实呢?您是否必须解决并允许您的Swagger文档出错?我在这里向您展示 ...

  9. Spring Boot 2.x基础教程:Swagger静态文档的生成

    前言 通过之前的两篇关于Swagger入门以及具体使用细节的介绍之后,我们已经能够轻松地为Spring MVC的Web项目自动构建出API文档了.如果您还不熟悉这块,可以先阅读: Spring Boo ...

最新文章

  1. pendo android,Pendo
  2. html邮件链接和锚点链接
  3. 网络流24题-魔术球问题
  4. visualstudio开始调试不执行_攻击者是如何滥用msvsmon和Windows远程调试器的
  5. apache在windows上开启gzip的方法
  6. 包管理工具conda极简教程
  7. 【蓝桥杯单片机】NE555在CT107D上的使用
  8. CentOS7安装VPP(FD.io)
  9. LYNC 2010 安装指南和心得
  10. ORB_SLAM3编译
  11. SNF软件开发机器人2018最新更新内容
  12. Win11新Bug任务栏图标不显示的解决方法
  13. kali 密码破解汇总
  14. 【英语词组】恋恋不忘Day4-2
  15. pytorch 基本数学运算
  16. 3款移动应用数据统计分析平台对比
  17. 如何快速发表职称论文
  18. html消除绝对定位的影响,css怎么清除绝对定位?
  19. python处理teradata数据库_【Python连接数据库】Python连接Teradata数据库-ODBC方式(pyodbc包和teradata包)...
  20. 计算机专业高薪职位,2016年高薪职业类排行榜揭晓,计算机专业最吃香

热门文章

  1. 操作系统 chapter 12 死锁
  2. Vue.js——60分钟快速入门
  3. linux命令之find和locate
  4. 关于tomcat8在windows2008下高并发下问题的解决方案
  5. 读《人,绩效和职业道德》有感
  6. 输入一颗二元查找树,将该树转换为它的镜像
  7. What you need to know about AllowUnsafeUpdates (Part 1) [转载]
  8. 一步一步学Silverlight 2系列(34):使用Silverlight Streaming托管Silverlight应用程序_转载...
  9. 手机能上网,电脑联不上网
  10. MySQL自增长主键探究