在團隊開發(fā)中霞丧,一個好的 API 文檔不但可以減少大量的溝通成本斥赋,還可以幫助一位新人快速上手業(yè)務(wù)。傳統(tǒng)的做法是由開發(fā)人員創(chuàng)建一份 RESTful API 文檔來記錄所有的接口細節(jié)昌罩,并在程序員之間代代相傳琐驴。
這種做法存在以下幾個問題:
API 接口眾多,細節(jié)復(fù)雜嘀韧,需要考慮不同的HTTP請求類型篇亭、HTTP頭部信息、HTTP請求內(nèi)容等锄贷,想要高質(zhì)量的完成這份文檔需要耗費大量的精力译蒂;
難以維護。隨著需求的變更和項目的優(yōu)化谊却、推進柔昼,接口的細節(jié)在不斷地演變,接口描述文檔也需要同步修訂炎辨,可是文檔和代碼處于兩個不同的媒介捕透,除非有嚴格的管理機制,否則很容易出現(xiàn)文檔碴萧、接口不一致的情況
Swagger2 的出現(xiàn)就是為了從根本上解決上述問題乙嘀。它作為一個規(guī)范和完整的框架,可以用于生成勿决、描述乒躺、調(diào)用和可視化 RESTful 風格的 Web 服務(wù):
接口文檔在線自動生成,文檔隨接口變動實時更新低缩,節(jié)省維護成本
支持在線接口測試嘉冒,不依賴第三方工具
SpringBoot 集成 Swagger2
1、pom.xml 添加 Maven 依賴
<dependencies>
...
<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger-ui -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
?
<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger2 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
</dependencies>
2咆繁、創(chuàng)建 Swagger2Configuration.java
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
?
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
?
@Configuration
@EnableSwagger2
public class Swagger2Configuration {
?
//api接口包掃描路徑
public static final String SWAGGER_SCAN_BASE_PACKAGE = "com.muyao.galaxy";
?
public static final String VERSION = "1.0.0";
?
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage(SWAGGER_SCAN_BASE_PACKAGE))
.paths(PathSelectors.any()) // 可以根據(jù)url路徑設(shè)置哪些請求加入文檔讳推,忽略哪些請求
.build();
}
?
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("單詞計數(shù)服務(wù)") //設(shè)置文檔的標題
.description("單詞計數(shù)服務(wù) API 接口文檔") // 設(shè)置文檔的描述
.version(VERSION) // 設(shè)置文檔的版本信息-> 1.0.0 Version information
.termsOfServiceUrl("http://www.baidu.com") // 設(shè)置文檔的License信息->1.3 License information
.build();
}
}
Swagger2Configuration.java 配置類的內(nèi)容不多,配置完成后也很少變化玩般,簡單了解即可银觅。
如上代碼所示,通過 @Configuration
注解坏为,讓 Spring 加載該配置類究驴。再通過 @EnableSwagger2
注解來啟用Swagger2。成員方法 createRestApi
函數(shù)創(chuàng)建 Docket
的Bean之后匀伏,apiInfo()
用來創(chuàng)建該 Api 的基本信息(這些基本信息會展現(xiàn)在文檔頁面中)洒忧。select()
函數(shù)返回一個 ApiSelectorBuilder
實例用來控制哪些接口暴露給 Swagger 來展現(xiàn),本例采用指定掃描的包路徑來定義够颠,Swagger 會掃描該包下所有 Controller 定義的 API熙侍,并產(chǎn)生文檔內(nèi)容(除了被 @ApiIgnore
指定的請求)。
3、API 接口編寫
在完成了上述配置后蛉抓,其實已經(jīng)可以產(chǎn)生文檔內(nèi)容庆尘,但是這樣的文檔主要針對請求本身,而描述主要來源于函數(shù)等命名產(chǎn)生巷送,對用戶并不友好驶忌,我們通常需要自己增加一些說明來豐富文檔內(nèi)容。
@Api(description = "生產(chǎn)者進程API接口")
@RestController
@RequestMapping("/producer")
public class ActiveMQProducer {
private static final Logger logger = LoggerFactory.getLogger(ActiveMQConsumer.class);
@Value(value = "${mq.active.count-queue-name}")
private String COUNT_QUEUE_NAME;
@Value(value = "${mq.active.query-queue-name}")
private String QUERY_QUEUE_NAME;
@Autowired
private ActiveMQManager mqManager;
@ApiOperation(value="發(fā)送解析文本", notes="發(fā)送解析文本", produces="application/json")
@RequestMapping(value="/sendText", produces={ MediaType.APPLICATION_JSON_UTF8_VALUE }, consumes={ MediaType.APPLICATION_JSON_UTF8_VALUE }, method=RequestMethod.POST)
public String sendText(@RequestBody String text) {
logger.info("發(fā)送的文本內(nèi)容:{}", text);
try {
mqManager.sendMsg(COUNT_QUEUE_NAME, text);
} catch (Exception e){
e.printStackTrace();
logger.error(e.getMessage());
}
return "SUCESS";
}
@ApiOperation(value="查詢單詞計數(shù)", notes="查詢單詞計數(shù)", produces="application/json")
@ApiImplicitParam(name = "word", value = "單詞", paramType = "query", required = true, dataType = "String")
@RequestMapping(value="/queryWordCount", produces={ MediaType.APPLICATION_JSON_UTF8_VALUE }, consumes={ MediaType.APPLICATION_JSON_UTF8_VALUE }, method=RequestMethod.POST)
public String queryWordCount(@RequestBody String word) {
logger.info("查詢單詞計數(shù):{}", word);
try {
mqManager.sendMsg(QUERY_QUEUE_NAME, word);
} catch (Exception e){
e.printStackTrace();
logger.error(e.getMessage());
}
return "SUCESS";
}
}
本接口示例了 @ApiOperation 和 @ApiImplicitParam 兩個注解的使用惩系。
Swagger 通過注解定制接口對外展示的信息位岔,這些信息包括接口名如筛、請求方法堡牡、參數(shù)、返回信息等杨刨。更多注解類型:
- @Api:修飾整個類晤柄,描述Controller的作用
- @ApiOperation:描述一個類的一個方法,或者說一個接口
- @ApiParam:單個參數(shù)描述
- @ApiModel:用對象來接收參數(shù)
- @ApiProperty:用對象接收參數(shù)時妖胀,描述對象的一個字段
- @ApiResponse:HTTP響應(yīng)其中1個描述
- @ApiResponses:HTTP響應(yīng)整體描述
- @ApiIgnore:使用該注解忽略這個API
- @ApiError :發(fā)生錯誤返回的信息
- @ApiImplicitParam:描述一個請求參數(shù)芥颈,可以配置參數(shù)的中文含義,還可以給參數(shù)設(shè)置默認值
- @ApiImplicitParams:描述由多個 @ApiImplicitParam 注解的參數(shù)組成的請求參數(shù)列表
4赚抡、啟動 SpringBoot 應(yīng)用
SpringBoot 啟動成功后爬坑,訪問 http://localhost:8080/swagger-ui.html
展開類維度的接口列表,如 active-mq-producer
涂臣,頁面會列出該類中定義的所有接口盾计。點擊任意接口,可查看該接口的 url 路徑赁遗、請求類型署辉、參數(shù)描述和返回碼說明等信息。
點擊右上角的 “Try it out岩四!”
按鈕哭尝,錄入請求信息,點擊 Execute
按鈕完成一次請求調(diào)用剖煌!
5材鹦、在 Security 中的配置
Spring Boot 項目中如果集成了 Spring Security,在不做額外配置的情況下耕姊,Swagger2 文檔會被攔截桶唐。解決方法是在 Security 的配置類中重寫 configure 方法添加白名單即可:
@Override
public void configure ( WebSecurity web) throws Exception {
web.ignoring()
.antMatchers("/swagger-ui.html")
.antMatchers("/v2/**")
.antMatchers("/swagger-resources/**");
}