前置說明
編寫API文檔,可能是最爲枯燥無味的工作了,大部分程序猿都不太願意幹這個活,但是大部分人還是苦於沒有找到更好的解決方案來處理這個問題,或者之前的代碼不允許去做類似的工作,只能老老實實自己去寫API。
但是,作爲新項目啓動,必須提前考慮這個問題,解放程序員雙手,讓他們擼更多業務代碼,而不是整天糾結文檔方面的工作。
如果要做到這些,那必須有一個前置條件,那就是你的代碼足夠規範,實體類命名、註釋完備、數據庫描述完善。
數據庫結構
數據表結構必須規範、字段描述、表描述、主鍵策略、非空定義
CREATE TABLE `t_website` (
`id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT '網站ID',
`name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL DEFAULT '' COMMENT '網站名稱',
`logo` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT '' COMMENT '網站LOGO',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='網站信息';
出入參實體
如下,是一個比較規範的入參樣本,使用ApiModelProperty描述好了字段的基本信息、是否非空
/**
* <p>
* 語言設置請求類
* </p>
*
* @author 聰明笨狗
* @since 2019-04-13 10:47
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@ApiModel(value="網站信息", description="網站信息")
public class WebsiteReqDTO implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "網站ID", required=true)
private String id;
@ApiModelProperty(value = "網站名稱", required=true)
private String name;
@ApiModelProperty(value = "網站LOGO")
private String logo;
}
控制器類
如下,是一個比較規範的Controller控制器類
/**
* <p>
* 語言設置控制器
* </p>
*
* @author 聰明笨狗
* @since 2019-04-13 10:47
*/
@Api(tags={"網站信息"})
@Controller
@RequestMapping("/admin/website")
public class WebsiteController extends BaseController {
@Autowired
private WebsiteService baseService;
/**
* 添加
* @param reqDTO
* @return
*/
@ResponseBody
@ApiOperation(value = "添加")
@RequestMapping(value = "/add", method = { RequestMethod.POST})
public ApiRest<WebsiteRespDTO> add(@RequestBody WebsiteReqDTO reqDTO) {
//保存數據並返回數據
}
/**
* 根據ID修改
* @param reqDTO
* @return
*/
@ResponseBody
@ApiOperation(value = "根據ID修改")
@RequestMapping(value = "/update", method = { RequestMethod.POST})
public ApiRest edit(@RequestBody WebsiteReqDTO reqDTO) {
//保存數據並返回數據
}
/**
* 批量刪除
* @param reqDTO
* @return
*/
@ResponseBody
@ApiOperation(value = "批量刪除")
@RequestMapping(value = "/delete", method = { RequestMethod.POST})
public ApiRest edit(@RequestBody DeleteReqDTO reqDTO) {
//刪除數據並返回結果
}
/**
* 查找詳情
* @param reqDTO
* @return
*/
@ResponseBody
@ApiOperation(value = "查找詳情")
@RequestMapping(value = "/detail", method = { RequestMethod.POST})
public ApiRest<WebsiteRespDTO> find(@RequestBody FindReqDTO reqDTO) {
//返回詳情數據
}
}
Swagger配置
Swagger2.java
/**
* Swagger2配置
*/
@Configuration
@EnableSwagger2
@ConfigurationProperties(prefix = "swagger")
public class Swagger2 {
private static final String BASE_PACKAGE = "com.mycompany";
@Value("${swagger.enable}")
private boolean enableSwagger;
@Bean
public Docket helloDocket() {
return new Docket(DocumentationType.SWAGGER_2)
//用於分組功能,也可以不配置
.groupName("admin")
//註冊整體api信息
.apiInfo(apiInfo())
//swagger功能是否啓用,可以通過配置設置,也可以先寫死
.enable(enableSwagger)
.select()
//指定掃描的包
.apis(RequestHandlerSelectors.basePackage(BASE_PACKAGE))
//設置此組只匹配admin/**的請求
.paths(PathSelectors.ant("/admin/**"))
.build();
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder().title("後臺管理項目")
.description("通用的CRUD")
.contact(new Contact("Van", "", ""))
.version("1.0.0")
.build();
}
pom.xml
<!-- 引入swagger2包 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<!-- 引入自帶UI,可選-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
以上配置好以後就OK了,項目啓動以後,通過以下URL可以訪問到API文檔的JSON數據:
帶分組的:
http://localhost:8080/v2/api-docs?group=admin
不帶分組的:
http://localhost:8080/v2/api-docs
訪問URL返回以下JSON:
{
"swagger": "2.0",
"info": {
"description": "通用的CRUD",
"version": "1.0.0",
"title": "後臺管理項目",
"contact": {
"name": "Van"
}
},
"host": "127.0.0.1:8080",
"basePath": "/",
"tags": [{
"name": "網站信息",
"description": "WebsiteController"
}],
"paths": {
"/admin/website/add": {
"post": {
"tags": ["網站信息"],
"summary": "添加",
"operationId": "addUsingPOST",
"consumes": ["application/json"],
"produces": ["*/*"],
"parameters": [{
"in": "body",
"name": "reqDTO",
"description": "reqDTO",
"required": true,
"schema": {
"$ref": "#/definitions/網站信息"
}
}],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/接口響應"
}
},
"201": {
"description": "Created"
},
"401": {
"description": "Unauthorized"
},
"403": {
"description": "Forbidden"
},
"404": {
"description": "Not Found"
}
},
"deprecated": false
}
},
"/admin/website/delete": {
"post": {
"tags": ["網站信息"],
"summary": "批量刪除",
"operationId": "editUsingPOST",
"consumes": ["application/json"],
"produces": ["*/*"],
"parameters": [{
"in": "body",
"name": "reqDTO",
"description": "reqDTO",
"required": true,
"schema": {
"$ref": "#/definitions/刪除參數"
}
}],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/接口響應"
}
},
"201": {
"description": "Created"
},
"401": {
"description": "Unauthorized"
},
"403": {
"description": "Forbidden"
},
"404": {
"description": "Not Found"
}
},
"deprecated": false
}
},
"/admin/website/detail": {
"post": {
"tags": ["網站信息"],
"summary": "查找詳情",
"operationId": "findUsingPOST",
"consumes": ["application/json"],
"produces": ["*/*"],
"parameters": [{
"in": "body",
"name": "reqDTO",
"description": "reqDTO",
"required": true,
"schema": {
"$ref": "#/definitions/查詢參數"
}
}],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/接口響應«網站信息»"
}
},
"201": {
"description": "Created"
},
"401": {
"description": "Unauthorized"
},
"403": {
"description": "Forbidden"
},
"404": {
"description": "Not Found"
}
},
"deprecated": false
}
},
"/admin/website/update": {
"post": {
"tags": ["網站信息"],
"summary": "根據ID修改",
"operationId": "editUsingPOST_1",
"consumes": ["application/json"],
"produces": ["*/*"],
"parameters": [{
"in": "body",
"name": "reqDTO",
"description": "reqDTO",
"required": true,
"schema": {
"$ref": "#/definitions/網站信息"
}
}],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/接口響應"
}
},
"201": {
"description": "Created"
},
"401": {
"description": "Unauthorized"
},
"403": {
"description": "Forbidden"
},
"404": {
"description": "Not Found"
}
},
"deprecated": false
}
}
},
"definitions": {
"刪除參數": {
"type": "object",
"required": ["ids"],
"properties": {
"ids": {
"type": "array",
"description": "要刪除的ID列表",
"items": {
"type": "string"
}
}
},
"title": "刪除參數",
"description": "刪除參數"
},
"接口響應": {
"type": "object",
"required": ["code"],
"properties": {
"code": {
"type": "integer",
"format": "int32",
"description": "響應代碼,0爲成功,1爲失敗"
},
"data": {
"type": "object",
"description": "響應內容"
},
"msg": {
"type": "string",
"description": "響應消息"
},
"success": {
"type": "boolean"
}
},
"title": "接口響應",
"description": "接口響應"
},
"接口響應«List«網站信息»»": {
"type": "object",
"required": ["code"],
"properties": {
"code": {
"type": "integer",
"format": "int32",
"description": "響應代碼,0爲成功,1爲失敗"
},
"data": {
"type": "array",
"description": "響應內容",
"items": {
"$ref": "#/definitions/網站信息"
}
},
"msg": {
"type": "string",
"description": "響應消息"
},
"success": {
"type": "boolean"
}
},
"title": "接口響應«List«網站信息»»",
"description": "接口響應"
},
"接口響應«網站信息»": {
"type": "object",
"required": ["code"],
"properties": {
"code": {
"type": "integer",
"format": "int32",
"description": "響應代碼,0爲成功,1爲失敗"
},
"data": {
"description": "響應內容",
"$ref": "#/definitions/網站信息"
},
"msg": {
"type": "string",
"description": "響應消息"
},
"success": {
"type": "boolean"
}
},
"title": "接口響應«網站信息»",
"description": "接口響應"
},
"查詢參數": {
"type": "object",
"required": ["id"],
"properties": {
"id": {
"type": "string",
"description": "要查詢的ID"
}
},
"title": "查詢參數",
"description": "查詢參數"
},
"網站信息": {
"type": "object",
"required": ["code", "id", "name", "state"],
"properties": {
"id": {
"type": "string",
"description": "網站ID"
},
"name": {
"type": "string",
"description": "網站名稱"
},
"logo": {
"type": "string",
"description": "網站LOGO"
}
},
"title": "網站信息",
"description": "網站信息"
}
}
}
導入接口到YAPI
切換到YAPI的數據管理選項卡
有兩種方式導入YAPI
1、將JSON保存到文件,上傳。
2、如果你的項目有外網URL的話,直接開啓URL導入。
導入好的接口
總結
只要你的代碼足夠規範,使用此方案進行文檔導入,可以節省90%的文檔工作量,生成的內容只需要少量修改就可以直接交於前端同事對接,是不是美滋滋?
另外提供一個自己寫的SpringCloud代碼生成器,只需要要貼入建表語句,即可一鍵生成符合規範的DTO/Entity/Controller/Service/Mapper/
http://www.5f66.com/code-generate.html
注:以上部分內容經過加工,只做演示用,並非真實代碼