集成 Spring Doc 接口文檔和 knife4j-SpringBoot 2.7.2 實(shí)戰(zhàn)基礎(chǔ)

優(yōu)雅哥 SpringBoot 2.7 實(shí)戰(zhàn)基礎(chǔ) - 04 -集成 Spring Doc 接口文檔和 knife4j

前面已經(jīng)集成 MyBatis Plus、Druid 數(shù)據(jù)源,開發(fā)了 5 個(gè)接口辩涝。在測(cè)試這 5 個(gè)接口時(shí)使用了 HTTP Client 或 PostMan轴踱,無論是啥都比較麻煩:得自己寫請(qǐng)求地址 URL飞傀、請(qǐng)求參數(shù)等朴摊,于是多年前就出現(xiàn)了 Swagger 這個(gè)玩意葛圃。Swagger 可以自動(dòng)生成接口文檔千扔,還能很方便的測(cè)試各個(gè)接口。但不幸的是库正,MVN Repository 上面 Springfox Swagger2 的版本停止于 2020 年 7月曲楚,而寫下這篇文章是 2022 年 8 月,已經(jīng)兩年過去沒有動(dòng)靜了褥符,與此同時(shí)龙誊,springdoc-openapi 悄然出現(xiàn)。

spring doc open api 支持 Open API 3喷楣、Swagger-ui等趟大,可以很方便與 Spring Boot 整合鹤树,配置和使用與 Springfox Swagger2 類似。

1 集成 Spring Doc

1.1 添加依賴

springdoc-openapi 不是 Spring Framework 官方團(tuán)隊(duì)開發(fā)的逊朽,而是社區(qū)項(xiàng)目罕伯,沒有包含在 spring-boot-dependencies 中。故需要先定義版本號(hào):

<properties>
        ....
    <springdoc-openapi-ui.version>1.6.9</springdoc-openapi-ui.version>
</properties>

添加依賴:

<dependency>
    <groupId>org.springdoc</groupId>
    <artifactId>springdoc-openapi-ui</artifactId>
    <version>${springdoc-openapi-ui.version}</version>
</dependency>

該依賴?yán)锩媸褂昧?swagger-ui叽讳,以HTML形式展示文檔追他。

1.2 編寫配置類

其實(shí)配置類寫不寫都可以,如果不寫配置類岛蚤,就通過注解定義文檔信息就可以邑狸。創(chuàng)建類:com.yygnb.demo.config.SpringDocConfig

package com.yygnb.demo.config;

import io.swagger.v3.oas.models.ExternalDocumentation;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Info;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class SpringDocConfig {

    private String title = "Hero SpringBoot Demo";
    private String description = "Hero Demo for usage of Spring Boot";
    private String version = "v0.0.1";
    private String websiteName = "Hero Website";
    private String websiteUrl = "http://www.yygnb.com";

    @Bean
    public OpenAPI heroOpenAPI() {
        return new OpenAPI()
                .info(new Info().title(title)
                        .description(description)
                        .version(version))
                .externalDocs(new ExternalDocumentation().description(websiteName)
                        .url(websiteUrl));
    }
}

上面的配置定義了展示的文檔的信息,與界面上對(duì)應(yīng)關(guān)系如下:

1.jpg

在配置文件中除了可以配置文檔的信息灭美,還可以配置文檔分組推溃、Authorization 等,在后面的企業(yè)級(jí)實(shí)戰(zhàn)文章中會(huì)具體描寫届腐,將會(huì)在網(wǎng)關(guān)層 spring cloud gateway 中集成所有微服務(wù)的接口。

1.3 配置yml

在 application.yml 配置 springdoc:

# 接口文檔
springdoc:
  packages-to-scan: com.yygnb.demo.controller
  swagger-ui:
    enabled: true

這兩項(xiàng)不配置也可以蜂奸,packages-to-scan 默認(rèn)為啟動(dòng)類所在的路徑犁苏;springdoc.swagger-ui.enabled 默認(rèn)為true,配置后可以在不同的環(huán)境中開啟或關(guān)閉扩所。

1.4 添加注解

springdoc-openapi 與 springfox-swagger2 提供的注解有很大差別:

swagger 2 spring doc 描述
@Api @Tag 修飾 controller 類围详,類的說明
@ApiOperation @Operation 修飾 controller 中的接口方法,接口的說明
@ApiModel @Schema 修飾實(shí)體類祖屏,該實(shí)體的說明
@ApiModelProperty @Schema 修飾實(shí)體類的屬性助赞,實(shí)體類中屬性的說明
@ApiImplicitParams @Parameters 接口參數(shù)集合
@ApiImplicitParam @Parameter 接口參數(shù)
@ApiParam @Parameter 接口參數(shù)

修改實(shí)體類 Computer,添加 springdoc-openapi 注解:

@Schema(title = "電腦")
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class Computer implements Serializable {

    private static final long serialVersionUID = 1L;

    @TableId(value = "id", type = IdType.AUTO)
    private Long id;

    @Schema(title = "尺寸")
    private BigDecimal size;

    @Schema(title = "操作系統(tǒng)")
    private String operation;

    @Schema(title = "年份")
    private String year;
}

修改控制器 ComputerController袁勺,添加注解:

@Tag(name = "電腦相關(guān)接口")
@RequiredArgsConstructor
@RestController
@RequestMapping("/computer")
public class ComputerController {

    private final IComputerService computerService;

    @Operation(summary = "根據(jù)id查詢電腦")
    @GetMapping("/{id}")
    public Computer findById(
            @Parameter(name = "id", required = true, description = "電腦id") @PathVariable Long id) {
        return this.computerService.getById(id);
    }

    @Operation(summary = "分頁查詢電腦列表")
    @Parameters(value = {
            @Parameter(name = "page", description = "頁面雹食,從1開始", example = "2"),
            @Parameter(name = "size", description = "每頁大小", example = "10")
    })
    @GetMapping("/find-page/{page}/{size}")
    public Page<Computer> findPage(@PathVariable Integer page, @PathVariable Integer size) {
        return this.computerService.page(new Page<>(page, size));
    }

    @Operation(summary = "新增電腦")
    @PostMapping()
    public Computer save(@RequestBody Computer computer) {
        computer.setId(null);
        this.computerService.save(computer);
        return computer;
    }

    @Operation(summary = "根據(jù)id修改電腦")
    @PutMapping("/{id}")
    public Computer update(
            @Parameter(name = "id", required = true, description = "電腦id") @PathVariable Long id,
            @RequestBody Computer computer) {
        computer.setId(id);
        this.computerService.updateById(computer);
        return computer;
    }

    @Operation(summary = "根據(jù)id刪除電腦")
    @DeleteMapping("/{id}")
    @Parameter(name = "id", required = true, description = "電腦id")
    public void delete(@PathVariable Long id) {
        this.computerService.removeById(id);
    }
}

1.5 運(yùn)行測(cè)試

啟動(dòng)服務(wù),在瀏覽器中訪問:

http://localhost:9099/swagger-ui/index.html
2.jpg

2 api-docs

在文檔標(biāo)題下面有一個(gè)小鏈接:/v3/api-docs期丰,點(diǎn)擊該鏈接群叶,會(huì)在新頁面中顯示一大坨 JSON 數(shù)據(jù)。

3.jpg

看似很無聊的數(shù)據(jù)钝荡,卻有著重大意義街立,swagger-ui 就是通過這些數(shù)據(jù)渲染出頁面的。此外埠通,這些JSON數(shù)據(jù)在某種程度上可以簡(jiǎn)化前端的開發(fā)及前后端網(wǎng)絡(luò)請(qǐng)求的工作量赎离。

hero-admin-ui

優(yōu)雅哥正在開發(fā)的基于 Vue 3 + TypeScript 的開源項(xiàng)目 hero-admin-ui,其特色就是基于 JSON Schema 的表單和列表端辱。通過 JSON Schema 可以快速渲染出一個(gè)列表梁剔、表單虽画,甚至是搜索頁和詳情表單頁。如果獨(dú)立使用 hero-admin-ui憾朴,需要手動(dòng)編寫 JSON Schema狸捕,但如果后端接口整合了 Swagger 或 Spring Doc,上面 api-docs 返回的 JSON众雷,就包含了 JSON Schema灸拍,二者結(jié)合可以快速實(shí)現(xiàn)搜索頁、表單頁等砾省。目前 hero-admin-ui 已發(fā)布在 npmjs 上鸡岗,也已經(jīng)提交到 github上,大家可以搜索關(guān)鍵字 hero-admin-ui 查看编兄。在后面的實(shí)戰(zhàn)篇中轩性,前端部分將會(huì)使用這個(gè)組件庫實(shí)現(xiàn)前端頁面。

4.jpg

3 自定義配置

在 ”1.2 編寫配置類“ 一節(jié)狠鸳,文檔信息都是寫死在代碼中的揣苏,如果多個(gè)微服務(wù)都要集成 spring doc,可以把前面寫的 SpringDocConfig 提取到公共模塊中件舵,通過maven 依賴引用卸察,在 application.yml 中配置不同的變量。

3.1 添加依賴

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-configuration-processor</artifactId>
    <optional>true</optional>
</dependency>

配置該依賴的目的是在編寫 application.yml 時(shí)铅祸,自定義的屬性有代碼提示坑质。它會(huì)生成配置元數(shù)據(jù),無需自己手動(dòng)編寫临梗。

3.2 定義配置的實(shí)體類

創(chuàng)建 com.yygnb.demo.config.DocInfo涡扼,將 SpringDocConfig 中寫死的屬性都移到這個(gè)配置實(shí)體類中:

@Data
@Component
@ConfigurationProperties(prefix = "doc-info")
public class DocInfo {

    private String title = "Demo Title";
    private String description = "Demo Description";
    private String version = "v0.0.1";
    private String websiteName = "Demo Website";
    private String websiteUrl = "http://www.yygnb.com";
}

注解 @ConfigurationProperties(prefix = "doc-info") 聲明配置屬性,在 application.yml 配置時(shí)就可以使用 doc-info盟庞。

3.3 重構(gòu) SpringDocConfig

在 SpringDocConfig 中引入 DocInfo吃沪,并通過構(gòu)造函數(shù)進(jìn)行注入:

@RequiredArgsConstructor
@Configuration
public class SpringDocConfig {

    private final DocInfo docInfo;

    @Bean
    public OpenAPI springShopOpenAPI() {
        return new OpenAPI()
                .info(new Info().title(docInfo.getTitle())
                        .description(docInfo.getDescription())
                        .version(docInfo.getVersion()))
                .externalDocs(new ExternalDocumentation().description(docInfo.getWebsiteName())
                        .url(docInfo.getWebsiteUrl()));
    }
}

補(bǔ)充一個(gè)小點(diǎn):注解 @RequiredArgsConstructor 是 lombok 中提供的,它等價(jià)于在類中編寫了方法:

public SpringDocConfig(DocInfo docInfo) {
    this.docInfo = docInfo;
}

構(gòu)造注入時(shí)茫经,在構(gòu)造函數(shù)中寫大量的屬性巷波,毫無意義。既然已經(jīng)使用了@Data 注解卸伞,為啥不用 @RequiredArgsConstructor 呢抹镊?

3.4 使用自定義配置

自定義配置已經(jīng)完成,可以在 application.yml 中使用 DocInfo 對(duì)應(yīng)的配置了:

doc-info:
  title: SpringBoot Demo演示
  description: 學(xué)習(xí) Spring Boot 2.7.2

DocInfo 所有屬性都定義了默認(rèn)值荤傲,在 application.yml 可以覆蓋默認(rèn)值垮耳,如上面的 titledescription 屬性。重啟服務(wù)查看運(yùn)行效果:

5.jpg

4 集成 knife4j

在之前 springfox-swagger 的時(shí)代,很多同學(xué)不喜歡 swagger-ui 的界面風(fēng)格终佛,會(huì)集成 knife4j 的 ui俊嗽。Spring Doc 也可以集成 knife4j。

如果要使用 knife4j 铃彰,Spring Doc 的配置中需要添加分組配置绍豁,我們這里添加一個(gè)最簡(jiǎn)單的分組配置。

com.yygnb.demo.config.SpringDocConfig

@RequiredArgsConstructor
@Configuration
public class SpringDocConfig {

    private final DocInfo docInfo;

    @Bean
    public OpenAPI heroOpenAPI() {
        return new OpenAPI()
                .info(new Info().title(docInfo.getTitle())
                        .description(docInfo.getDescription())
                        .version(docInfo.getVersion()))
                .externalDocs(new ExternalDocumentation().description(docInfo.getWebsiteName())
                        .url(docInfo.getWebsiteUrl()));
    }

    @Bean
    public GroupedOpenApi publicApi() {
        return GroupedOpenApi.builder()
                .group(docInfo.getTitle())
                .pathsToMatch("/**")
                .build();
    }
}

如果不添加這個(gè) GroupedOpenApi 實(shí)例牙捉,knife4j ui就顯示不出來竹揍。

在 pom.xml 中引入 knife4j

<properties>
...
    <knife4j-springdoc-ui.version>3.0.3</knife4j-springdoc-ui.version>
</properties>

<dependencies>
...
    <dependency>
        <groupId>com.github.xiaoymin</groupId>
        <artifactId>knife4j-springdoc-ui</artifactId>
        <version>${knife4j-springdoc-ui.version}</version>
    </dependency>
</dependencies>

啟動(dòng)服務(wù),訪問:

http://localhost:9099/doc.html

顯示 knife4j 的ui:

6.jpg

今日優(yōu)雅哥(工\/youyacoder)學(xué)習(xí)結(jié)束邪铲,期待關(guān)注留言分享~~

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末芬位,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子带到,更是在濱河造成了極大的恐慌昧碉,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,324評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件揽惹,死亡現(xiàn)場(chǎng)離奇詭異被饿,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)搪搏,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,356評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門锹漱,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人慕嚷,你說我怎么就攤上這事”厦冢” “怎么了喝检?”我有些...
    開封第一講書人閱讀 162,328評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)撼泛。 經(jīng)常有香客問我挠说,道長(zhǎng),這世上最難降的妖魔是什么愿题? 我笑而不...
    開封第一講書人閱讀 58,147評(píng)論 1 292
  • 正文 為了忘掉前任损俭,我火速辦了婚禮,結(jié)果婚禮上潘酗,老公的妹妹穿的比我還像新娘杆兵。我一直安慰自己,他們只是感情好仔夺,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,160評(píng)論 6 388
  • 文/花漫 我一把揭開白布琐脏。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪日裙。 梳的紋絲不亂的頭發(fā)上吹艇,一...
    開封第一講書人閱讀 51,115評(píng)論 1 296
  • 那天,我揣著相機(jī)與錄音昂拂,去河邊找鬼受神。 笑死,一個(gè)胖子當(dāng)著我的面吹牛格侯,可吹牛的內(nèi)容都是我干的鼻听。 我是一名探鬼主播,決...
    沈念sama閱讀 40,025評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼养交,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼精算!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起碎连,我...
    開封第一講書人閱讀 38,867評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤灰羽,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后鱼辙,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體廉嚼,經(jīng)...
    沈念sama閱讀 45,307評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,528評(píng)論 2 332
  • 正文 我和宋清朗相戀三年倒戏,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了怠噪。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,688評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡杜跷,死狀恐怖傍念,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情葛闷,我是刑警寧澤憋槐,帶...
    沈念sama閱讀 35,409評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站淑趾,受9級(jí)特大地震影響阳仔,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜扣泊,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,001評(píng)論 3 325
  • 文/蒙蒙 一近范、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧延蟹,春花似錦评矩、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,657評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春果录,著一層夾襖步出監(jiān)牢的瞬間上枕,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,811評(píng)論 1 268
  • 我被黑心中介騙來泰國(guó)打工弱恒, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留辨萍,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,685評(píng)論 2 368
  • 正文 我出身青樓返弹,卻偏偏與公主長(zhǎng)得像锈玉,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子义起,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,573評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容