Swagger 入门使用
概述
使用 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
使用步驟
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 接口, 并且可以實現代碼與接口文檔的一致, 保證接口的一致. 結合當前項目還是非常棒的選擇
?
參考資料
轉載于:https://www.cnblogs.com/Zereker/p/11390850.html
總結
以上是生活随笔為你收集整理的Swagger 入门使用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux服务源码安装后开机自启动04-
- 下一篇: flutter_web 实战之文章列表与