Swagger介绍及使用
導(dǎo)語(yǔ):
相信無(wú)論是前端還是后端開(kāi)發(fā),都或多或少地被接口文檔折磨過(guò)。前端經(jīng)常抱怨后端給的接口文檔與實(shí)際情況不一致。后端又覺(jué)得編寫(xiě)及維護(hù)接口文檔會(huì)耗費(fèi)不少精力,經(jīng)常來(lái)不及更新。其實(shí)無(wú)論是前端調(diào)用后端,還是后端調(diào)用后端,都期望有一個(gè)好的接口文檔。但是這個(gè)接口文檔對(duì)于程序員來(lái)說(shuō),就跟注釋一樣,經(jīng)常會(huì)抱怨別人寫(xiě)的代碼沒(méi)有寫(xiě)注釋,然而自己寫(xiě)起代碼起來(lái),最討厭的,也是寫(xiě)注釋。所以僅僅只通過(guò)強(qiáng)制來(lái)規(guī)范大家是不夠的,隨著時(shí)間推移,版本迭代,接口文檔往往很容易就跟不上代碼了。
Swagger是什么?它能干什么?
發(fā)現(xiàn)了痛點(diǎn)就要去找解決方案。解決方案用的人多了,就成了標(biāo)準(zhǔn)的規(guī)范,這就是Swagger的由來(lái)。通過(guò)這套規(guī)范,你只需要按照它的規(guī)范去定義接口及接口相關(guān)的信息。再通過(guò)Swagger衍生出來(lái)的一系列項(xiàng)目和工具,就可以做到生成各種格式的接口文檔,生成多種語(yǔ)言的客戶端和服務(wù)端的代碼,以及在線接口調(diào)試頁(yè)面等等。這樣,如果按照新的開(kāi)發(fā)模式,在開(kāi)發(fā)新版本或者迭代版本的時(shí)候,只需要更新Swagger描述文件,就可以自動(dòng)生成接口文檔和客戶端服務(wù)端代碼,做到調(diào)用端代碼、服務(wù)端代碼以及接口文檔的一致性。
但即便如此,對(duì)于許多開(kāi)發(fā)來(lái)說(shuō),編寫(xiě)這個(gè)yml或json格式的描述文件,本身也是有一定負(fù)擔(dān)的工作,特別是在后面持續(xù)迭代開(kāi)發(fā)的時(shí)候,往往會(huì)忽略更新這個(gè)描述文件,直接更改代碼。久而久之,這個(gè)描述文件也和實(shí)際項(xiàng)目漸行漸遠(yuǎn),基于該描述文件生成的接口文檔也失去了參考意義。所以作為Java屆服務(wù)端的大一統(tǒng)框架Spring,迅速將Swagger規(guī)范納入自身的標(biāo)準(zhǔn),建立了Spring-swagger項(xiàng)目,后面改成了現(xiàn)在的Springfox。通過(guò)在項(xiàng)目中引入Springfox,可以掃描相關(guān)的代碼,生成該描述文件,進(jìn)而生成與代碼一致的接口文檔和客戶端代碼。這種通過(guò)代碼生成接口文檔的形式,在后面需求持續(xù)迭代的項(xiàng)目中,顯得尤為重要和高效。
框架說(shuō)明及使用
1.說(shuō)明
現(xiàn)在SWAGGER官網(wǎng)主要提供了幾種開(kāi)源工具,提供相應(yīng)的功能。可以通過(guò)配置甚至是修改源碼以達(dá)到你想要的效果。
Swagger Codegen: 通過(guò)Codegen 可以將描述文件生成html格式和cwiki形式的接口文檔,同時(shí)也能生成多鐘語(yǔ)言的服務(wù)端和客戶端的代碼。支持通過(guò)jar包,docker,node等方式在本地化執(zhí)行生成。也可以在后面的Swagger Editor中在線生成。
Swagger UI:提供了一個(gè)可視化的UI頁(yè)面展示描述文件。接口的調(diào)用方、測(cè)試、項(xiàng)目經(jīng)理等都可以在該頁(yè)面中對(duì)相關(guān)接口進(jìn)行查閱和做一些簡(jiǎn)單的接口請(qǐng)求。該項(xiàng)目支持在線導(dǎo)入描述文件和本地部署UI項(xiàng)目。
Swagger Editor: 類似于markendown編輯器的編輯Swagger描述文件的編輯器,該編輯支持實(shí)時(shí)預(yù)覽描述文件的更新效果。也提供了在線編輯器和本地部署編輯器兩種方式。
Swagger Inspector: 感覺(jué)和postman差不多,是一個(gè)可以對(duì)接口進(jìn)行測(cè)試的在線版的postman。比在Swagger UI里面做接口請(qǐng)求,會(huì)返回更多的信息,也會(huì)保存你請(qǐng)求的實(shí)際請(qǐng)求參數(shù)等數(shù)據(jù)。
Swagger Hub:集成了上面所有項(xiàng)目的各個(gè)功能,你可以以項(xiàng)目和版本為單位,將你的描述文件上傳到Swagger Hub中。在Swagger Hub中可以完成上面項(xiàng)目的所有工作,需要注冊(cè)賬號(hào),分免費(fèi)版和收費(fèi)版。
PS:
Springfox Swagger: Spring 基于swagger規(guī)范,可以將基于SpringMVC和Spring Boot項(xiàng)目的項(xiàng)目代碼,自動(dòng)生成JSON格式的描述文件。本身不是屬于Swagger官網(wǎng)提供的,在這里列出來(lái)做個(gè)說(shuō)明,方便后面作一個(gè)使用的展開(kāi)。
2.基于Spring框架的Swagger流程應(yīng)用
這里不會(huì)介紹Swagger的工具具體如何使用,不會(huì)講yml或者json格式描述文件的語(yǔ)法規(guī)范,也不會(huì)講如何在SpringMVC或者Spring Boot中配置Springfox-swagger。這些都能從網(wǎng)上找到,而且配置起來(lái)都非常的簡(jiǎn)單。
這里想講的是如何結(jié)合現(xiàn)有的工具和功能,設(shè)計(jì)一個(gè)流程,去保證一個(gè)項(xiàng)目從開(kāi)始開(kāi)發(fā)到后面持續(xù)迭代的時(shí)候,以最小代價(jià)去維護(hù)代碼、接口文檔以及Swagger描述文件。
2.1 項(xiàng)目開(kāi)始階段
一般來(lái)說(shuō),接口文檔都是由服務(wù)端來(lái)編寫(xiě)的。在項(xiàng)目開(kāi)發(fā)階段的時(shí)候,服務(wù)端開(kāi)發(fā)可以視情況來(lái)決定是直接編寫(xiě)服務(wù)端調(diào)用層代碼,還是寫(xiě)Swagger描述文件。建議是如果項(xiàng)目啟動(dòng)階段,就已經(jīng)搭好了后臺(tái)框架,那可以直接編寫(xiě)服務(wù)端被調(diào)用層的代碼(即controller及其入?yún)⒊鰠?duì)象),然后通過(guò)Springfox-swagger 生成swagger json描述文件。如果項(xiàng)目啟動(dòng)階段并沒(méi)有相關(guān)后臺(tái)框架,而前端對(duì)接口文檔追得緊,那就建議先編寫(xiě)swagger描述文件,通過(guò)該描述文件生成接口文檔。后續(xù)后臺(tái)框架搭好了,也可以生成相關(guān)的服務(wù)端代碼。
2.1 項(xiàng)目迭代階段
到這個(gè)階段,事情就簡(jiǎn)單很多了。后續(xù)后臺(tái)人員,無(wú)需關(guān)注Swagger描述文件和接口文檔,有需求變更導(dǎo)致接口變化,直接寫(xiě)代碼就好了。把調(diào)用層的代碼做個(gè)修改,然后生成新的描述文件和接口文檔后,給到前端即可。真正做到了一勞永逸。
2.3流程
總結(jié)一下就是通過(guò)下面這兩種流程中的一種,可以做到代碼和接口文檔的一致性,服務(wù)端開(kāi)發(fā)再也不用花費(fèi)精力去維護(hù)接口文檔。
流程一
流程二
給Mock系統(tǒng)的正常請(qǐng)求及響應(yīng)全流程數(shù)據(jù)
很多時(shí)候,如果你能在提供接口文檔的同時(shí),把所有接口的模擬請(qǐng)求響應(yīng)數(shù)據(jù)也提供給前端。或者有Mock系統(tǒng),直接將這些模擬數(shù)據(jù)錄入到Mock系統(tǒng)中,那將會(huì)提高前端的開(kāi)發(fā)效率,減少許多發(fā)生在聯(lián)調(diào)時(shí)候才會(huì)發(fā)生的問(wèn)題。
通過(guò)適當(dāng)?shù)卦诖a中加入swagger的注解,可以讓你的接口文檔描述信息更加詳細(xì),如果你把每個(gè)出入?yún)?shù)的示例值都配上,那前端就可以直接在接口文檔中拿到模擬數(shù)據(jù)。相關(guān)的注解類及參數(shù)配置可以參考文末他人寫(xiě)的技術(shù)文章,這里也不作展開(kāi)了。
相關(guān)示例注解代碼和效果圖如下:
#####Controller代碼 @Override@ApiOperation(value = "post請(qǐng)求調(diào)用示例", notes = "invokePost說(shuō)明", httpMethod = "POST")public FFResponseModel<DemoOutputDto> invokePost(@ApiParam(name="傳入對(duì)象",value="傳入json格式",required=true) @RequestBody @Valid DemoDto input) {log.info("/testPost is called. input=" + input.toString());return new FFResponseModel(Errcode.SUCCESS_CODE, Errcode.SUCCESS_MSG);}#####接口請(qǐng)求入?yún)?duì)象 @Data @ApiModel(value="演示類",description="請(qǐng)求參數(shù)類" ) public class DemoDto implements Serializable {private static final long serialVersionUID = 1L;@NotNull@ApiModelProperty(value = "defaultStr",example="mockStrValue")private String strDemo;@NotNull@ApiModelProperty(example="1234343523",required = true)private Long longNum;@NotNull@ApiModelProperty(example="111111.111")private Double doubleNum;@NotNull@ApiModelProperty(example="2018-12-04T13:46:56.711Z")private Date date;}#####接口請(qǐng)求出參公共類 @ApiModel(value="基礎(chǔ)返回類",description="基礎(chǔ)返回類") public class FFResponseModel<T> implements Serializable {private static final long serialVersionUID = -2215304260629038881L;// 狀態(tài)碼@ApiModelProperty(example="成功")private String code;// 業(yè)務(wù)提示語(yǔ)@ApiModelProperty(example="000000")private String msg;// 數(shù)據(jù)對(duì)象private T data;... }#####接口請(qǐng)求出參實(shí)際數(shù)據(jù)對(duì)象 @Data public class DemoOutputDto {private String res;@NotNull@ApiModelProperty(value = "defaultOutputStr",example="mockOutputStrValue")private String outputStrDemo;@NotNull@ApiModelProperty(example="6666666",required = true)private Long outputLongNum;@NotNull@ApiModelProperty(example="88888.888")private Double outputDoubleNum;@NotNull@ApiModelProperty(example="2018-12-12T11:11:11.111Z")private Date outputDate;}效果圖
模擬請(qǐng)求數(shù)據(jù)報(bào)文:
模擬返回?cái)?shù)據(jù)報(bào)文:
總結(jié)
其實(shí)歸根到底,使用Swagger,就是把相關(guān)的信息存儲(chǔ)在它定義的描述文件里面(yml或json格式),再通過(guò)維護(hù)這個(gè)描述文件可以去更新接口文檔,以及生成各端代碼。而Springfox-swagger,則可以通過(guò)掃描代碼去生成這個(gè)描述文件,連描述文件都不需要再去維護(hù)了。所有的信息,都在代碼里面了。代碼即接口文檔,接口文檔即代碼。
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的Swagger介绍及使用的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: javascript引擎V8精要(2)
- 下一篇: javascript精要(1)-scri