Spring Boot 集成 Swagger 構(gòu)建接口文檔

在應用開發(fā)過程中經(jīng)常需要對其他應用或者客戶端提供 RESTful API 接口,尤其是在版本快速迭代的開發(fā)過程中,修改接口的同時還需要同步修改對應的接口文檔命斧,這使我們總是做著重復的工作莽红,并且如果忘記修改接口文檔,就可能造成不必要的麻煩衅胀。

為了解決這些問題岔乔,Swagger 就孕育而生了,那讓我們先簡單了解下滚躯。

Swagger 簡介

Swagger 是一個規(guī)范和完整的框架雏门,用于生成、描述掸掏、調(diào)用和可視化 RESTful 風格的 Web 服務茁影。

總體目標是使客戶端和文件系統(tǒng)作為服務器,以同樣的速度來更新丧凤。文件的方法募闲、參數(shù)和模型緊密集成到服務器端的代碼中,允許 API 始終保持同步愿待。

下面我們在 Spring Boot 中集成 Swagger 來構(gòu)建強大的接口文檔浩螺。

Spring Boot 集成 Swagger

Spring Boot 集成 Swagger 主要分為以下三步:

  1. 加入 Swagger 依賴
  2. 加入 Swagger 文檔配置
  3. 使用 Swagger 注解編寫 API 文檔

加入依賴

首先創(chuàng)建一個項目,在項目中加入 Swagger 依賴仍侥,項目依賴如下所示:

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.9.2</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.9.2</version>
        </dependency>

加入配置

接下來在 config 包下創(chuàng)建一個 Swagger 配置類 Swagger2Configuration要出,在配置類上加入注解 @EnableSwagger2,表明開啟 Swagger农渊,注入一個 Docket 類來配置一些 API 相關信息患蹂,apiInfo() 方法內(nèi)定義了幾個文檔信息,代碼如下:

@Configuration
@EnableSwagger2
public class Swagger2Configuration {

    @Bean
    public Docket createRestApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .select()
                // swagger 文檔掃描的包
                .apis(RequestHandlerSelectors.basePackage("com.wupx.interfacedoc.controller"))
                .paths(PathSelectors.any())
                .build();
    }

    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("測試接口列表")
                .description("Swagger2 接口文檔")
                .version("v1.0.0")
                .contact(new Contact("wupx", "https://www.tianheyu.top", "wupx@qq.com"))
                .license("Apache License, Version 2.0")
                .licenseUrl("http://www.apache.org/licenses/LICENSE-2.0.html")
                .build();
    }
}

列舉其中幾個文檔信息說明下:

  • title:接口文檔的標題
  • description:接口文檔的詳細描述
  • termsOfServiceUrl:一般用于存放公司的地址
  • version:API 文檔的版本號
  • contact:維護人砸紊、維護人 URL 以及 email
  • license:許可證
  • licenseUrl:許可證 URL

編寫 API 文檔

domain 包下創(chuàng)建一個 User 實體類传于,使用 @ApiModel 注解表明這是一個 Swagger 返回的實體,@ApiModelProperty 注解表明幾個實體的屬性醉顽,代碼如下(其中 getter/setter 省略不顯示):

@ApiModel(value = "用戶", description = "用戶實體類")
public class User {

    @ApiModelProperty(value = "用戶 id", hidden = true)
    private Long id;

    @ApiModelProperty(value = "用戶姓名")
    private String name;

    @ApiModelProperty(value = "用戶年齡")
    private String age;

    // getter/setter
}

最后沼溜,在 controller 包下創(chuàng)建一個 UserController 類,提供用戶 API 接口(未使用數(shù)據(jù)庫)游添,代碼如下:

@RestController
@RequestMapping("/users")
@Api(tags = "用戶管理接口")
public class UserController {

    Map<Long, User> users = Collections.synchronizedMap(new HashMap<>());

    @GetMapping("/")
    @ApiOperation(value = "獲取用戶列表", notes = "獲取用戶列表")
    public List<User> getUserList() {
        return new ArrayList<>(users.values());
    }

    @PostMapping("/")
    @ApiOperation(value = "創(chuàng)建用戶")
    public String addUser(@RequestBody User user) {
        users.put(user.getId(), user);
        return "success";
    }

    @GetMapping("/{id}")
    @ApiOperation(value = "獲取指定 id 的用戶")
    @ApiImplicitParam(name = "id", value = "用戶 id", paramType = "query", dataTypeClass = Long.class, defaultValue = "999", required = true)
    public User getUserById(@PathVariable Long id) {
        return users.get(id);
    }

    @PutMapping("/{id}")
    @ApiOperation(value = "根據(jù) id 更新用戶")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "用戶 id", defaultValue = "1"),
            @ApiImplicitParam(name = "name", value = "用戶姓名", defaultValue = "wupx"),
            @ApiImplicitParam(name = "age", value = "用戶年齡", defaultValue = "18")
    })
    public User updateUserById(@PathVariable Long id, @RequestParam String name, @RequestParam Integer age) {
        User user = users.get(id);
        user.setName(name);
        user.setAge(age);
        return user;
    }

    @DeleteMapping("/{id}")
    @ApiOperation(value = "刪除用戶", notes = "根據(jù) id 刪除用戶")
    @ApiImplicitParam(name = "id", value = "用戶 id", dataTypeClass = Long.class, required = true)
    public String deleteUserById(@PathVariable Long id) {
        users.remove(id);
        return "success";
    }
}

啟動項目盛末,訪問 http://localhost:8080/swagger-ui.html弹惦,可以看到我們定義的文檔已經(jīng)在 Swagger 頁面上顯示了,如下圖所示:

到此為止悄但,我們就完成了 Spring Boot 與 Swagger 的集成棠隐。

同時 Swagger 除了接口文檔功能外,還提供了接口調(diào)試功能檐嚣,以創(chuàng)建用戶接口為例助泽,單擊創(chuàng)建用戶接口,可以看到接口定義的參數(shù)嚎京、返回值嗡贺、響應碼等,單擊 Try it out 按鈕鞍帝,然后點擊 Execute 就可以發(fā)起調(diào)用請求诫睬、創(chuàng)建用戶,如下圖所示:

注解介紹

由于 Swagger 2 提供了非常多的注解供開發(fā)使用帕涌,這里列舉一些比較常用的注解摄凡。

@Api

@Api 用在接口文檔資源類上,用于標記當前類為 Swagger 的文檔資源蚓曼,其中含有幾個常用屬性:

  • value:定義當前接口文檔的名稱亲澡。
  • description:用于定義當前接口文檔的介紹。
  • tag:可以使用多個名稱來定義文檔纫版,但若同時存在 tag 屬性和 value 屬性床绪,則 value 屬性會失效。
  • hidden:如果值為 true其弊,就會隱藏文檔癞己。

@ApiOperation

@ApiOperation 用在接口文檔的方法上,主要用來注解接口梭伐,其中包含幾個常用屬性:

  • value:對API的簡短描述痹雅。
  • note:API的有關細節(jié)描述。
  • esponse:接口的返回類型(注意:這里不是返回實際響應籽御,而是返回對象的實際結(jié)果)。
  • hidden:如果值為 true惰匙,就會在文檔中隱藏技掏。

@ApiResponse、@ApiResponses

@ApiResponses 和 @ApiResponse 二者配合使用返回 HTTP 狀態(tài)碼项鬼。@ApiResponses 的 value 值是 @ApiResponse 的集合哑梳,多個 @ApiResponse 用逗號分隔,其中 @ApiResponse 包含的屬性如下:

  • code:HTTP狀態(tài)碼绘盟。
  • message:HTTP狀態(tài)信息鸠真。
  • responseHeaders:HTTP 響應頭悯仙。

@ApiParam

@ApiParam 用于方法的參數(shù),其中包含以下幾個常用屬性:

  • name:參數(shù)的名稱吠卷。
  • value:參數(shù)值锡垄。
  • required:如果值為 true,就是必傳字段祭隔。
  • defaultValue:參數(shù)的默認值货岭。
  • type:參數(shù)的類型。
  • hidden:如果值為 true疾渴,就隱藏這個參數(shù)千贯。

@ApiImplicitParam、@ApiImplicitParams

二者配合使用在 API 方法上搞坝,@ApiImplicitParams 的子集是 @ApiImplicitParam 注解搔谴,其中 @ApiImplicitParam 注解包含以下幾個參數(shù):

  • name:參數(shù)的名稱。
  • value:參數(shù)值桩撮。
  • required:如果值為 true敦第,就是必傳字段。
  • defaultValue:參數(shù)的默認值距境。
  • dataType:數(shù)據(jù)的類型申尼。
  • hidden:如果值為 true,就隱藏這個參數(shù)垫桂。
  • allowMultiple:是否允許重復师幕。

@ResponseHeader

API 文檔的響應頭,如果需要設置響應頭诬滩,就將 @ResponseHeader 設置到 @ApiResponseresponseHeaders 參數(shù)中霹粥。@ResponseHeader 提供了以下幾個參數(shù):

  • name:響應頭名稱。
  • description:響應頭備注疼鸟。

@ApiModel

設置 API 響應的實體類后控,用作 API 返回對象。@ApiModel 提供了以下幾個參數(shù):

  • value:實體類名稱空镜。
  • description:實體類描述浩淘。
  • subTypes:子類的類型。

@ApiModelProperty

設置 API 響應實體的屬性吴攒,其中包含以下幾個參數(shù):

  • name:屬性名稱张抄。
  • value:屬性值。
  • notes:屬性的注釋洼怔。
  • dataType:數(shù)據(jù)的類型署惯。
  • required:如果值為 true,就必須傳入這個字段镣隶。
  • hidden:如果值為 true极谊,就隱藏這個字段诡右。
  • readOnly:如果值為 true,字段就是只讀的轻猖。
  • allowEmptyValue:如果為 true帆吻,就允許為空值。

到此為止蜕依,我們就介紹完了 Swagger 提供的主要注解桅锄。

總結(jié)

Swagger 可以輕松地整合到 Spring Boot 中構(gòu)建出強大的 RESTful API 文檔,可以減少我們編寫接口文檔的工作量样眠,同時接口的說明內(nèi)容也整合入代碼中友瘤,可以讓我們在修改代碼邏輯的同時方便的修改接口文檔說明,另外 Swagger 也提供了頁面測試功能來調(diào)試每個 RESTful API檐束。

如果項目中還未使用辫秧,不防嘗試一下,會發(fā)現(xiàn)效率會提升不少被丧。

本文的完整代碼在 https://github.com/wupeixuan/SpringBoot-Learninterface-doc 目錄下盟戏。

最好的關系就是互相成就,大家的在看甥桂、轉(zhuǎn)發(fā)柿究、留言三連就是我創(chuàng)作的最大動力。

參考

http://swagger.io

https://github.com/wupeixuan/SpringBoot-Learn

《Spring Boot 2 實戰(zhàn)之旅》

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末黄选,一起剝皮案震驚了整個濱河市蝇摸,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌办陷,老刑警劉巖貌夕,帶你破解...
    沈念sama閱讀 216,651評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異民镜,居然都是意外死亡啡专,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,468評論 3 392
  • 文/潘曉璐 我一進店門制圈,熙熙樓的掌柜王于貴愁眉苦臉地迎上來们童,“玉大人,你說我怎么就攤上這事鲸鹦』劭猓” “怎么了?”我有些...
    開封第一講書人閱讀 162,931評論 0 353
  • 文/不壞的土叔 我叫張陵亥鬓,是天一觀的道長完沪。 經(jīng)常有香客問我域庇,道長嵌戈,這世上最難降的妖魔是什么覆积? 我笑而不...
    開封第一講書人閱讀 58,218評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮熟呛,結(jié)果婚禮上宽档,老公的妹妹穿的比我還像新娘。我一直安慰自己庵朝,他們只是感情好吗冤,可當我...
    茶點故事閱讀 67,234評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著九府,像睡著了一般椎瘟。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上侄旬,一...
    開封第一講書人閱讀 51,198評論 1 299
  • 那天肺蔚,我揣著相機與錄音,去河邊找鬼儡羔。 笑死宣羊,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的汰蜘。 我是一名探鬼主播仇冯,決...
    沈念sama閱讀 40,084評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼族操!你這毒婦竟也來了苛坚?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,926評論 0 274
  • 序言:老撾萬榮一對情侶失蹤坪创,失蹤者是張志新(化名)和其女友劉穎炕婶,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體莱预,經(jīng)...
    沈念sama閱讀 45,341評論 1 311
  • 正文 獨居荒郊野嶺守林人離奇死亡柠掂,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,563評論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了依沮。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片涯贞。...
    茶點故事閱讀 39,731評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖危喉,靈堂內(nèi)的尸體忽然破棺而出宋渔,到底是詐尸還是另有隱情,我是刑警寧澤辜限,帶...
    沈念sama閱讀 35,430評論 5 343
  • 正文 年R本政府宣布皇拣,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏氧急。R本人自食惡果不足惜颗胡,卻給世界環(huán)境...
    茶點故事閱讀 41,036評論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望吩坝。 院中可真熱鬧毒姨,春花似錦、人聲如沸钉寝。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,676評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽嵌纲。三九已至俘枫,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間逮走,已是汗流浹背崩哩。 一陣腳步聲響...
    開封第一講書人閱讀 32,829評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留言沐,地道東北人邓嘹。 一個月前我還...
    沈念sama閱讀 47,743評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像险胰,于是被迫代替她去往敵國和親汹押。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,629評論 2 354