原文連接:html
Swagger 官網是這麼描述它的:The Best APIs are Built with Swagger Tools
。java
Swagger 是一套基於 OpenAPI 規範構建的開源工具,能夠幫助咱們設計、構建、記錄以及使用 Rest API。Swagger 主要包含了如下三個部分:git
Spring Boot 使得開發 RESTful 服務變得簡單。那麼編寫 Spring Boot 接口,爲什麼要用 Swagger 呢?github
pom.xml
引入 Swagger 相關的依賴:web
<!-- swagger2 --> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>${swagger.version}</version> </dependency> <!-- swagger2 ui --> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>${swagger.version}</version> </dependency>
使用 property
定義了 Swagger 的版本,所以還須要添加:spring
<swagger.version>2.9.2</swagger.version>
依賴說明:shell
springfox-swagger2
Swagger 的 Java 實現springfox-swagger-ui
Swagger UI 頁面的依賴使用註解 @Configuration
編寫 Swagger 配置類—— SwaggerConfig
。數據庫
新建 config
的包,建立 SwaggerConifg
的配置類:編程
//經過@Configuration註解,讓Spring來加載該類配置 @Configuration //經過@EnableSwagger2註解來啓用Swagger2 @EnableSwagger2 //@ConditionalOnExpression 爲Spring的註解,用戶是否實例化本類,用因而否啓用Swagger的判斷(生產環境須要屏蔽Swagger) @ConditionalOnExpression("${swagger.enable:true}") public class SwaggerConfig { // select()函數返回一個ApiSelectorBuilder實例用來控制哪些接口暴露給Swagger來展示,本例採用指定掃描的包路徑來定義, // Swagger會掃描該包下全部Controller定義的API,併產生文檔內容(除了被@ApiIgnore指定的請求) @Bean public Docket createRestApi() { // apiInfo()用來建立該Api的基本信息(這些基本信息會展示在文檔頁面中 ApiInfo apiInfo = new ApiInfoBuilder() .title("標題: Spring Boot 項目集成 Swagger 示例文檔") .description("描述: 個人博客地址是 https://michael728.github.io") .termsOfServiceUrl("https://michael728.github.io/") .version("1.0") .build(); Docket docket = new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo) // select()函數返回一個ApiSelectorBuilder實例 .select() // 決定了暴露哪些接口給 Swagger .paths(regex("/api/.*")) .build() .useDefaultResponseMessages(false) .glo return docket; } }
說明:segmentfault
@Configuration
是告訴 Spring Boot 須要加載這個配置類;@EnableSwagger2
是啓用 Swagger2,沒加的話,就看不到效果了;ApiInfo
對象用來設置一些文檔的版本號、聯繫人郵箱、網站、版權、開源協議等等信息(這些基本信息會展示在文檔頁面中)。並使用 Docket.apiInfo()
方法來設置;Docket
上增長篩選。提供了 apis()
和 paths()
兩個方法幫助咱們在不一樣級別上過濾接口:
apis()
這種方式咱們能夠指定包名的方式,讓 Swagger 只去某些包下面掃描;paths()
這種方式能夠經過篩選 API 的 url 來進行篩選;@ConditionalOnExpression("${swagger.enable:true}")
這個註解控制了是否啓用 Swagger,咱們須要在 appplication.properties
中加上 swagger.enable=true
咱們先介紹一下在用 Swagger 時的經常使用註解:
@API
類的註解,能夠給控制器增長描述和標籤信息。用在請求的類上,表明了這個類是 Swagger 的資源
tags
:控制器標籤,對該類進行「分類」,參數是個字符串數組,若是配置了多個值,會在多個分類中看到;value
:該參數沒什麼意義,在 UI 界面上並不顯示,可不用配置@ApiModel
類註解,對 API 涉及的對象作描述,可用於響應實體類,說明實體做用
value
Model 展現時的名稱,默認是 實體類的名稱,好比 UserEntity
;description
實體類的描述類成員變量的的註解:
@ApiModelProperty
用在實體類的屬性上
value
屬性字段描述;required
參數是否必選;name
重寫字段名稱;dataType
重寫字段類型;allowEmptyValue
是否容許爲空;allowbleValues
該字段容許的值。當咱們 API 某個參數爲枚舉類型時,使用這個參數就能夠清楚高速 API 使用者能容許傳入的值方法的註解:
@ApiOperation
描述方法的用途,用來展開對接口的描述
value
接口簡要描述;notes
接口發佈說明,詳細描述;@ApiImplicitParams
用於描述接口的非對象參數集,通常與 @ApiImplicitParams
組合使用@ApiImplicitParam
描述參數信息
value
參數意義的描述name
參數名字;required
默認 false
,參數是否必傳dataType
參數數據類型,只做爲標誌說明,並無實際驗證
Long
String
paramType
參數類型,表示參數放在哪裏
query
,默認值,Query String
的方式傳參,請求參數的獲取:@RequestParam
path
路徑參數,請求參數的獲取:@PathVariable
header
請求參數的獲取:@RequestHeader
@PathVariable
路徑參數,給相似 @GetMappIng("/user/{id}")
參數經過路徑傳入其餘:
@ApiIgnore
:用於類或者方法上,屏蔽接口不被顯示在頁面上;@Profile({"dev","test"})
:用於配置類上,表示對什麼環境啓用;@ApiParam
不能直接用在方法上,而是用在方法的形參定義中,下文會有示例;實體類示例:
@Data @ApiModel(value = "用戶實體") public class UserEntity { public static final long serialVersionUID = 1L; @ApiModelProperty(value = "用戶 id") private int id; @ApiModelProperty(value = "用戶名", required = true) private String userName; @ApiModelProperty(value = "密碼" ) private String passWord; @ApiModelProperty(value = "性別") private UserSexEnum userSex; @ApiModelProperty(value = "暱稱" ) private String nickName; public UserEntity(Integer id, String userName, String passWord) { this.id = id; this.userName = userName; this.passWord = passWord; } }
下面是一個控制類的示例:
@RestController @RequestMapping("/api/v1/") @Api(tags = {"用戶相關接口"}, value = "用戶模塊") public class UserController { // 模擬數據庫 public static List<UserEntity> users = new ArrayList<>(); static { UserEntity user1 = new UserEntity(1, "michael", "123"); UserEntity user2 = new UserEntity(2, "qq", "123"); UserEntity user3 = new UserEntity(3, "hh", "123"); users.add(user1); users.add(user2); users.add(user3); } @ApiOperation(value = "獲取用戶列表", notes = "獲取所有用戶信息") @RequestMapping(value = "/users", method = RequestMethod.GET) public List<UserEntity> getUsers() { return users; } @ApiOperation(value = "查詢單用戶", notes = "根據用戶id 查詢其信息") @ApiImplicitParam(name = "id", value = "用戶id", paramType = "query", required = true) @GetMapping("/user/{id}") public UserEntity getUser(@PathParam("id") int id) { UserEntity user = users.get(id); return user; } @ApiOperation(value = "存儲用戶信息", notes = "存儲用戶詳細信息") @RequestMapping(value = "/user", method = RequestMethod.POST) public UserEntity saveUser(@ApiParam(value = "用戶信息", required = true) @RequestBody UserEntity user) { users.add(user); return user; } @ApiOperation(value = "刪除用戶", notes = "根據用戶id刪除用戶信息") @ApiImplicitParams({ @ApiImplicitParam(name = "id", value = "用戶id", required = true, paramType = "path") }) @RequestMapping(value = "/user/{id}", method = RequestMethod.DELETE) public int deleteUser(@PathVariable("id") int id) { users.remove(id); return id; } @ApiOperation(value = "更新用戶信息", notes = "更新用戶的我的信息") @PutMapping("/user/") public UserEntity updateUser(@RequestBody UserEntity user) { int id = user.getId(); UserEntity oldUser = users.get(id); users.set(id, user); return user; } }
啓動應用,訪問 localhost:8080/swagger-ui.html
能夠訪問到 Swagger UI
,能夠點擊 Try it out
按鈕,調用 API:
頁面上還會有一個 Models 的分類。Swagger UI 會根據咱們在實體上使用的 @ApiModel
和 @ApiModelProperty
註解來自動補充實體以及其屬性的描述和備註。
開發 API,先了解一下有哪些 Web API 的風格吧:
GetUserInfo,CreateUser
;上文提到了 RESTful API 的概念,我以爲,不如趁機瞭解一下。由於在實際的項目中發現,並非每一個 Spring Boot 的開發人員都能意識到開發的 API 要儘可能符合 RESTful 規則的。REST 實際上只是一種設計風格,它並非標準。
術語:
Endpoint
終點,能夠理解爲路徑,表示 API 的具體網址。API(Application Programming Interface)
,應用程序編程接口REST
是 Representational State Transfer
的縮寫。若是一個架構符合 REST 原則,就稱它爲 RESTful 架構。RESTful API 就是 REST 風格的 API
在 RESTful 架構中,每一個網址表明一種資源(resource
),因此網址中不能有動詞,只能有名詞,並且所用的名詞每每與數據庫的表格名對應。
RESTful 的核心思想就是,客戶端發出的數據操做指令都是"動詞 + 賓語"的結構。好比,GET /articles
這個命令,GET
是動詞,/articles
是賓語。
對於資源的具體操做類型,由 HTTP 動詞表示(括號裏是對應的 SQL 命令):
還有兩個不經常使用的 HTTP 動詞:
知乎上的一個回答,我以爲很精闢:
一位答主給出的示例:
GET /rest/api/getDogs --> GET /rest/api/dogs 獲取全部小狗狗 GET /rest/api/addDogs --> POST /rest/api/dogs 添加一個小狗狗 GET /rest/api/editDogs/:dog_id --> PUT /rest/api/dogs/:dog_id 修改一個小狗狗 GET /rest/api/deleteDogs/:dog_id --> DELETE /rest/api/dogs/:dog_id 刪除一個小狗狗
若是記錄數量不少,服務器不可能都將它們返回給用戶。API 應該提供參數,過濾返回結果
?limit=10
:指定返回記錄的數量?offset=10
:指定返回記錄的開始位置。?page=2&per_page=100
:指定第幾頁,以及每頁的記錄數API 介紹
歡迎關注我的公衆號 「iPlayMichael」