可無注解的 SpringBoot API文檔生成工具


JApiDocs是一個無需額外注解、開箱即用的SpringBoot接口文檔生成工具。

前言

編寫和維護API文檔,對於后端程序員來說,是一件惱人但又不得不做的事情,我們都不喜歡寫文檔,除非項目前后端代碼都是自己寫的,否則API文檔將是前后端協作不可或缺的溝通載體。
最佳實踐是:先把接口設計好,在Mock的方法上寫注釋來生成API文檔,這樣做到前后端根據API文檔並行開發。

為什么引入JApiDocs

相比Swagger要寫一堆注解,Spring Rest Docs需要寫測試用例,才能生成API文檔,JApiDocs只要Controller類和方法的Java注釋寫完即可手動生成多種格式的API文檔。
如下的簡單一個參數的方法,Swagger要寫兩行又臭又長的注解,稍不留神就寫錯。

 
Swagger注解示例

 

先睹為快

沒有對比就沒有傷害,看一下我的java代碼,沒有任何多余的注解,只有常規的java規范方法注釋。

    /** * 示例生成api文檔方法 * * @param productId 年齡 * @param guo 姓氏 * @return 商品庫存DTO */ @PostMapping("/apiDocDemo") public ProductReduceStockDTO apiDocDemo(@RequestParam Long productId, @RequestParam String guo) { return new ProductReduceStockDTO().setProductId(productId); } 

 

 

生成后的Java API Doc如圖:
 
API Doc效果圖

快速上手

第一步

添加依賴

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

第二步

配置參數
你可以在任意一個類添加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書寫遵循一定的編碼規范。

1. 添加必要的代碼注釋

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

package cn.iocoder.springboot.lab52.productservice.controller; import cn.iocoder.springboot.lab52.productservice.dto.ProductReduceStockDTO; import cn.iocoder.springboot.lab52.productservice.service.ProductService; import io.github.yedaxia.apidocs.Docs; import io.github.yedaxia.apidocs.DocsConfig; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; /** * @description 商品相關操作控制器 * @ClassName: ProductController * @author: 郭秀志 jbcode@126.com * @date: 2020/6/23 20:56 * @Copyright: */ @RestController @RequestMapping("/product") public class ProductController { private Logger logger = LoggerFactory.getLogger(ProductController.class); @Autowired private ProductService productService; /** * 減庫存操作 * * @param productReduceStockDTO 商品及庫存的DTO,用於減庫存。 * @param guo 示例參數無意義。 * @return */ @PostMapping("/reduce-stock") public Boolean reduceStock(@RequestBody ProductReduceStockDTO productReduceStockDTO, @RequestParam String guo) { logger.info(guo + "[reduceStock] 收到減少庫存請求, 商品:{}, 價格:{}", productReduceStockDTO.getProductId(), productReduceStockDTO.getAmount()); try { productService.reduceStock(productReduceStockDTO.getProductId(), productReduceStockDTO.getAmount()); // 正常扣除庫存,返回 true return true; } catch (Exception e) { // 失敗扣除庫存,返回 false return false; } } /** * 示例生成api文檔方法 * * @param productId 年齡 * @param guo 姓氏 * @return 商品庫存DTO */ @PostMapping("/apiDocDemo") public ProductReduceStockDTO apiDocDemo(@RequestParam Long productId, @RequestParam String guo) { return new ProductReduceStockDTO().setProductId(productId); } public static void main(String[] args) { DocsConfig config = new DocsConfig(); config.setProjectPath("D:\\dev\\GitRepository\\seata-at-httpclient-demo\\seata-at-httpclient-demo-product-service"); // 項目根目錄 config.setProjectName("商品服務"); // 項目名稱 config.setApiVersion("V1.0"); // 聲明該API的版本 config.setDocsPath("d:\\Japidoc"); // 生成API 文檔所在目錄 config.setAutoGenerate(Boolean.TRUE); // 配置自動生成 Docs.buildHtmlDocs(config); // 執行生成文檔 } } 
/** * 商品減少庫存 DTO */ public class ProductReduceStockDTO { /** * 商品編號 */ private Long productId; /** * 數量 */ private Integer amount; 省略getter、setter方法,屬性的注釋將在文檔中被使用....... 

如果提交的表單是 application/x-www-form-urlencoded 類型的key/value格式,你可以在 SpringBoot 端通過在 @param 參數后添加字段解釋或者在相關的JavaBean對象里面添加解釋:

// 直接在java的 @param 注解中 
// 在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支持繼承、泛型、循環嵌套等復雜的類解析。

比如的apiDocDemo接口:


    /** * 示例生成api文檔方法 * * @param productId 年齡 * @param guo 姓氏 * @return 商品庫存DTO */ @PostMapping("/apiDocDemo") public ProductReduceStockDTO apiDocDemo(@RequestParam Long productId, @RequestParam String guo) { return new ProductReduceStockDTO().setProductId(productId); } 

ProductReduceStockDTO表明了該接口返回的數據結構,經過JApiDocs處理后是這樣的:

{ "productId": "long //商品編號", "amount": "int //數量" } 

如果你不是通過返回對象的形式,你也可以通過JApiDocs提供的@ApiDoc注解來聲明返回類型,你可以參考@ApiDoc章節的相關配置內容。

3. @ApiDoc

JApiDocs 默認只導出聲明了@ApiDoc的接口,我們前面通過設置 config.setAutoGenerate(Boolean.TRUE) 來解除了這個限制。

如果你不希望把所有的接口都導出,你可以把autoGenerate設置關閉,在相關Controller類或者接口方法上通過添加@ApiDoc來確定哪些接口需要導出。

@ApiDoc聲明在接口方法上的時候,它還擁有一些更靈活的設置,下面我們來看一下:

  • result: 這個可以直接聲明返回的對象類型,如果你聲明了,將會覆蓋SpringBoot的返回對象
  • url: 請求URL,擴展字段,用於支持非SpringBoot項目
  • method: 請求方法,擴展字段,用於支持非SpringBoot項目

例子:

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

4. @Ignore

如果你不想導出對象里面的某個字段,可以給這個字段加上@Ignore注解,這樣JApiDocs導出文檔的時候就會自動忽略掉了:

例子:

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

導出更多格式

導出markdown

config.addPlugin(new MarkdownDocPlugin()); 

導出 pdf 或者 word

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




免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM