当下很多公司都采取前后端分离的开发模式,前端和后端的工作由不同的工程师完成。在这种开发模式下,维持一份及时更新且完整的 Rest API 文档将会极大的提高我们的工作效率。传统意义上的文档都是后端开发人员手动编写的,相信大家也都知道这种方式很难保证文档的及时性,这种文档久而久之也就会失去其参考意义,反而还会加大我们的沟通成本。而 Swagger 给我们提供了一个全新的维护 API 文档的方式,下面我们就来了解一下它的优点:
1、代码变,文档变。只需要少量的注解,Swagger 就可以根据代码自动生成 API 文档,很好的保证了文档的时效性。
2、跨语言性,支持 40 多种语言。
3、Swagger UI 呈现出来的是一份可交互式的 API 文档,我们可以直接在文档页面尝试 API 的调用,省去了准备复杂的调用参数的过程。
4、还可以将文档规范导入相关的工具(例如 Postman、SoapUI), 这些工具将会为我们自动地创建自动化测试
我这里使用starter这种简单的方式来引入swagger
<dependency>
<groupId>com.spring4all</groupId>
<artifactId>swagger-spring-boot-starter</artifactId>
<version>1.9.0.RELEASE</version>
</dependency>
@Configuration
@EnableSwagger2Doc
public class SwaggerConfiguration {
@Autowired
private LXSwaggerProperties lxSwaggerProperties;
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
.paths(PathSelectors.any())
.build();
}
//基本信息的配置,信息会在api文档上显示
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title(lxSwaggerProperties.getTitle())
.version(lxSwaggerProperties.getVersion())
.build();
}
}
其中LXSwaggerProperties内容如下:
@Configuration
@ConfigurationProperties(prefix = "lx.swagger")
@Data
public class LXSwaggerProperties {
private String title = "lx接口文档";
private String version = "1.0";
}
有了这种灵活的配置,我们就可以在配置文件中定义title和version了,当然了,我们可以根据自己的实际情况暴露需要配置的属性。
需要注意的是,这里面的prefix不要使用swagger,不然的话,会出现title乱码的问题;
由于这个starter自动配置了Swagger,所以实际上已经存在了Docket,我们这种装配方式会导致启动失败,错误如下:
***************************
APPLICATION FAILED TO START
***************************
Description:
The bean 'createRestApi', defined in class path resource [com/firewolf/lx/config/SwaggerConfiguration.class], could not be registered. A bean with that name has already been defined in class path resource [com/spring4all/swagger/SwaggerAutoConfiguration.class] and overriding is disabled.
Action:
Consider renaming one of the beans or enabling overriding by setting spring.main.allow-bean-definition-overriding=true
我们根据它的提示,在配置文件加入以下配置即可:
spring.main.allow-bean-definition-overriding=true
值得一提的是:我们可以直接通过在配置文件中加入swagger.xxx的方式来配置swagger,从而替代现在的这个类,能够配置的属性在SwaggerProperties类里面。
filterChainDefinitionMap.put("/swagger-ui.html**", "anon");
filterChainDefinitionMap.put("/v2/api-docs", "anon");
filterChainDefinitionMap.put("/swagger-resources/**", "anon");
filterChainDefinitionMap.put("/webjars/**", "anon");
默认情况下,swagger会暴露所有的web类、方法、参数,这在很多时候其实不是我们想要的,我们可以通过以下几个方法进行限定。
①. 限定包下controller生成API文档
.apis(RequestHandlerSelectors.basePackage("com.firewolf"))
②. 限定有@Api注解的Controller生成API文档
.apis(RequestHandlerSelectors.withClassAnnotation(Api.class))
③. 限定有@ApiOperation注解的方法生成API文档
.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
④. 限定Model中的某些属性不生成文档
这个需要通过在属性上面添加如下注解来实现:
@ApiModelProperty(hidden = true)
@Api:放在请求的类上,与 @Controller 并列,说明类的作用,如用户模块,订单类等。
tags="说明该类的作用"
value="该参数没什么意义,所以不需要配置"
@ApiOperation:"用在请求的方法上,说明方法的作用"
value="说明方法的作用"
notes="方法的备注说明"
@ApiImplicitParams:用在请求的方法上,包含一组参数说明
@ApiImplicitParam:对单个参数的说明
name:参数名
value:参数的汉字说明、解释
required:参数是否必须传
paramType:参数放在哪个地方
· header --> 请求参数的获取:@RequestHeader
· query --> 请求参数的获取:@RequestParam
· path(用于restful接口)--> 请求参数的获取:@PathVariable
· body(请求体)--> @RequestBody User user
· form(普通表单提交)
dataType:参数类型,默认String,其它值dataType="int"
defaultValue:参数的默认值
@ApiResponses:方法返回对象的说明
@ApiResponse:每个参数的说明
code:数字,例如400
message:信息,例如"请求参数没填好"
response:抛出异常的类
@ApiModel:用于JavaBean的类上面,表示此 JavaBean 整体的信息
(这种一般用在post创建的时候,使用 @RequestBody 这样的场景,请求参数无法使用 @ApiImplicitParam 注解进行描述的时候 )