大家都知道Swagger是一個常用的Spring Boot介面文件生成工具,但是我們今天再介紹另外一個無需額外註解的 Spring Boot API文件生成神器,非常方便好用!

JApiDocs是一個無需額外註解、開箱即用的Spring Boot介面文件生成工具。

編寫和維護API文件這個事情,對於後端程式設計師來說,是一件惱人但又不得不做的事情,我們都不喜歡寫文件,但除非專案前後端程式碼都是自己寫的,否則API文件將是前後端協作中一個不可或缺的溝通介面。既然不可避免,那就想辦法弄個輪子吧。人生苦短,必須偷懶。

無圖無真相,生成文件的效果如下:

相比Swagger要寫一堆註解,Spring RestDocs需要寫測試用例,才能生成API文件。JApiDocs 具有無痛整合的特點,你只需花幾分鐘就能知道它怎麼用了。

入門

支援JDK:1.8+

快速開始

第一步:新增依賴

maven:

<dependency>
<groupId>io.github.yedaxia</groupId>
<artifactId>japidocs</artifactId>
<version>1.4.4</version>
</dependency>

gradle:

compile 'io.github.yedaxia:japidocs:1.4.4'

第二步:配置引數

你可以在任意一個main入口執行下面的程式碼:

DocsConfig config = new DocsConfig();
config.setProjectPath("your springboot project path"); // 專案根目錄
config.setProjectName("ProjectName"); // 專案名稱
config.setApiVersion("V1.0"); // 宣告該API的版本
config.setDocsPath("your api docs path"); // 生成API 文件所在目錄
config.setAutoGenerate(Boolean.TRUE); // 配置自動生成
Docs.buildHtmlDocs(config); // 執行生成文件

如果沒有意外,執行完上面的程式碼後,你就可以在配置的目錄中看到生成的文件了。

編碼規範

JApiDocs是通過解析Java原始碼來實現的,要使得JApiDocs正確工作,需要你在專案中的Controller書寫遵循一定的編碼規範。

你可以結合原始碼中 SpringDemo 這個模組來對照理解。

1. 新增必要的程式碼註釋

其中類註釋會對應到一級介面分組,你也可以通過@description來指定分組名稱;JApiDocs 會通過 @param 來尋找介面引數和進一步解析引數的內容。

/**
* 使用者介面
*/
@RequestMapping("/api/user/")
@RestController
public class UserController { /**
* 使用者列表
* @param listForm
*/
@RequestMapping(path = "list", method = {RequestMethod.GET, RequestMethod.POST} )
public ApiResult<PageResult<UserVO>> list(UserListForm listForm){
return null;
} /**
* 儲存使用者
* @param userForm
*/
@PostMapping(path = "save")
public ApiResult<UserVO> saveUser(@RequestBody UserForm userForm){
return null;
} /**
* 刪除使用者
* @param userId 使用者ID
*/
@PostMapping("delete")
public ApiResult deleteUser(@RequestParam Long userId){
return null;
}
}

如果提交的表單是 application/x-www-form-urlencoded 型別的key/value格式,你可以在 SpringBoot 端通過在 @param 引數後新增欄位解釋或者在相關的JavaBean物件裡面新增解釋:

// 直接在java的 @param 註解中
@param userId 使用者ID
// 在FormBean物件中
public class UserListForm extends PageForm{
private Integer status; //使用者狀態
private String name; //使用者名稱
}

這種格式對於到文件中的引數描述將是表格的形式:

引數名 型別 必須 描述
status int 使用者狀態
name string 使用者名稱

如果提交的表單是 application/json 型別的json資料格式,對應 SpringBoot 中的 @RequestBody 註解,在文件中則是 json 格式顯示:

{
"id": "long //使用者ID",
"name": "string //使用者名稱",
"phone": "long //電話",
"avatar": "string //頭像",
"gender": "byte //性別"
}

2. 介面宣告返回物件

我們知道,如果Controller聲明瞭@RestController,SpringBoot會把返回的物件直接序列成Json資料格式返回給前端。

JApiDocs也利用了這一特性來解析介面返回的結果,但由於JApiDocs是靜態解析原始碼的,因此你要明確指出返回物件的型別資訊,JApiDocs支援繼承、泛型、迴圈巢狀等複雜的類解析。

比如上面的saveUser介面:

 /**
* 儲存使用者
* @param userForm
*/
@PostMapping(path = "save")
public ApiResult<UserVO> saveUser(@RequestBody UserForm userForm){
return null;
}

ApiResult<UserVO>表明了該介面返回的資料結構,經過JApiDocs處理後是這樣的:

{
"code": "int",
"errMsg": "string",
"data": {
"userId": "string //使用者id",
"userName": "string //使用者名稱",
"friends": [
{
"userId": "string //使用者id",
"userName": "string //使用者名稱"
}
],
"readBooks": [
{
"bookId": "long //圖書id",
"bookName": "string //圖書名稱"
}
],
"isFollow": "boolean //是否關注"
}
}

如果你不是通過返回物件的形式,你也可以通過JApiDocs提供的@ApiDoc註解來宣告返回型別,你可以參考@ApiDoc章節的相關配置內容。

3. 介面物件在原始碼中

我們知道,經過編譯後的 class 位元組碼中是沒有註釋資訊的。所以為了讓JApiDcos能更好地工作,你的表單Bean類和返回類最好在原始碼中,否則生成的文件將會缺失說明資訊。

在1.4.2版本中,JApiDocs在找不到原始碼的情況下(依賴類在jar包中)也會通過嘗試反射的方式來解析欄位資訊,但這樣就沒有說明資訊了。

後續會計劃通過關聯原始碼的形式來解決這個問題。

高階配置

@ApiDoc

JApiDocs 預設只匯出聲明瞭@ApiDoc的介面,我們前面通過設定 config.setAutoGenerate(Boolean.TRUE) 來解除了這個限制。

如果你不希望把所有的介面都匯出,你可以把autoGenerate設定關閉,在相關Controller類或者介面方法上通過新增@ApiDoc來確定哪些介面需要匯出。

@ApiDoc宣告在介面方法上的時候,它還擁有一些更靈活的設定,下面我們來看一下:

  • result: 這個可以直接宣告返回的物件型別,如果你聲明瞭,將會覆蓋SpringBoot的返回物件
  • stringResult:返回字串,在返回結果比較簡單,而不想建立一個專門的返回類,則可以考慮使用這個屬性。
  • url: 請求URL,擴充套件欄位,用於支援非SpringBoot專案
  • method: 請求方法,擴充套件欄位,用於支援非SpringBoot專案

例子:

@ApiDoc(result = AdminVO.class, url = "/api/v1/admin/login2", method = "post")

stringResult 例項,在文件中將會自動格式化json字串:

@ApiDoc(stringResult = "{code: 0, data: 'success'}")
@GetMapping(value = "custom-json")
public Map customJsonResult(){}

@Ignore

忽略Controller

你只需要在Controller類上新增該註解即可,這樣,整個Controller的介面都會被忽略掉:


@Ignore
public class UserController { }

忽略介面

不難理解,就是在介面方法中新增@Ignore註解:


@Ignore
@PostMapping("save")
public ApiResult saveUser(){
return null;
}

忽略欄位

如果你不想匯出物件裡面的某個欄位,可以給這個欄位加上@Ignore註解,這樣JApiDocs匯出文件的時候就會自動忽略掉了:

例子:

public class UserForm{
@Ignore
private Byte gender; //性別
}

@description

在Controller類上使用

在類上使用@description,將會作為該Controller在文件上的導航標題,而不會使用上面的註釋內容。

/**
* 演示一些比較特殊的宣告方法
*
* @description 管理員介面
* @author yeguozhong yedaxia.github.com
*/
@Controller
public class AdminController {

在介面方法上使用

在方法中使用,則可以在介面方法下面新增一行說明:

/**
* 使用者列表
* @description 這是一行說明
* @param listForm
* @author yedaxia
*/
@RequestMapping(path = "list", method = {RequestMethod.GET, RequestMethod.POST} )
public ApiResult<PageResult<UserVO>> list(UserListForm listForm){}

匯出更多格式

匯出markdown

config.addPlugin(new MarkdownDocPlugin());

匯出 pdf 或者 word

你可以通過 pandoc 把 markdown 格式轉成 pdf 或者 word 格式。

自定義程式碼模板

JApiDocs 除了支援文件匯出,目前也支援生成了 Android 和 iOS 的返回物件程式碼,對應 Java 和 Object-C 語言,

如果你想修改程式碼模板,可以通過以下的方法:

第一步:定義程式碼模板

把原始碼中library專案resources目錄下的程式碼模板拷貝一份,其中,IOS_表示 Object-C 程式碼模板,JAVA_開頭表示 Java程式碼,

模板中類似${CLASS_NAME}的符號是替換變數,具體含義你可以結合生成的程式碼進行理解,然後按照你想要的程式碼模板進行修改即可。

第二步:選擇新的模板

通過DocsConfig配置模板路徑替換成新的模板:

docsConfig.setResourcePath("模板路徑");

新增更多功能

JApiDocs 提供了外掛介面,你可以通過外掛介面來實現更多豐富的功能,下面介紹如何新增外掛:

第一步:實現 IPluginSupport 介面

public class CustomPlugin implements IPluginSupport{

    @Override
public void execute(List<ControllerNode> controllerNodeList){
// 實現你自己的功能需求
}
}

第二步:新增外掛

 config.addPlugin(new CustomPlugin());

常見問題

1、如何排查錯誤?

關閉自動生成config.setAutoGenerate(Boolean.FALSE),使用@ApiDoc 來一個個介面匯出排查問題。

2、多模組找不到相關類原始碼?

如果原始碼路徑沒有全部識別出來,可以通過config.addJavaSrcPath來新增模組的原始碼路徑,注意要新增到src/main/java這一級。

知道的越多不知道的更多