前端 -> 前端控制层、视图层
后端 -> 后端控制层、服务层、数据访问层
API文档随着互联网技术的发展,现在的网站架构基本都由原来的后端渲染,变成了:前端渲染、前后端分离的形态,而且前端技术和后端技术在各自的道路上越走越远。
一个项目组可能由前端、后端、安卓、IOS等众多的开发人员或者众多开发团队组成。前端和后端唯一联系,变成了API接口;API文档自然就成了前后端开发人员联系的纽带,变得尤为的重要,
产生的问题现在都奉行前后端分离开发和微服务大行其道,分微服务及前后端分离后,内部的 API 共同成本巨大,开发的沟通成本就增加了
- 接口多且复杂;
- 细节之处繁杂:通讯协议、参数、返回值、接口说明、路径等;
- 接口的维护。功能接口是随着时间迭代升级的,因此这增加了接口文档的管理成本。
因此,团队内部的沟通,一直都是开发人员的一个痛点。而手动编写 api 文档,如有在Word上写的,有在对应的项目目录下readme.md上写的,不仅效率低,而且容易遗漏、不能及时同步更新。
Swagger2介绍Swagger是一款RESTful接口的文档在线自动生成、功能测试功能框架。一个规范和完整的框架,用于生成、描述、调用和可视化RESTful风格的Web服务,加上swagger-ui,可以有很好的呈现。
现如今市场上书写API文档的工具有很多,常见的有 postman、yapi、阿里的RAP 但是能称之为框架的,估计也只有swagger了。目前在后端领域,基本上是swagger的天下了。
swagger 优缺点- 集成方便,功能强大,号称世界上最流行的API框架
- 直接运行,在线测试API
- Restful Api 文档在线自动生成器 => API 文档 与API 定义同步更新
- 支持多种语言 (如:Java,PHP等)
- 代码耦合,需要注解支持,对接口的污染较大,但不影响程序性能
- 首先创建一个基础的SpringBoot web项目。您可以通过 Spring Initializr 页面生成一个空的 Spring Boot 项目,或者通过idea创建一个SpringBoot项目
添加依赖
-
Spring Boot的Web依赖
org.springframework.boot spring-boot-starter-web 集成swagger2
io.springfox springfox-swagger2 2.9.2
集成Swagger UI
io.springfox springfox-swagger-ui 2.9.2
4、编写HelloController,测试确保运行成功!
主要是添加注解@EnableSwagger2和定义Docket的bean类。
@Configuration//加载到springboot配置里面
@EnableSwagger2//开启swagger2
public class SwaggerConfig {
@Bean
public Docket docket() {
return new Docket(documentationType.SWAGGER_2)
.apiInfo(apiInfo())
.groupName("qlh")//组名称
.enable(true)
.select()
.apis(RequestHandlerSelectors.basePackage("com.tinygray.madison.controller"))
// .paths(PathSelectors.ant("/login
public ApiInfo apiInfo(){
// Contact contact = new Contact("XXX", "http://baidu.com", "email");
Contact contact = new Contact("", "", "");
return new ApiInfo(
"XXX的API接口",
"company接口",
"V1.0",
"urn:toVs",
contact,
"Apache 2.0",
"http://www.apache.org/licenses/LICENSE-2.0",
new ArrayList());
}
}
添加文档内容
一般上是在Controller,请求参数上进行注解
@Api(tags = "TestController测试")
@RestController
public class TestController {
@ApiOperation("login api")
@GetMapping("/")
public String login() {
return "Hello login ~";
}
@ApiOperation("helloWord Api")
@GetMapping("/index")
public String index() {
return "Hello World ~";
}
@ApiOperation("admin Api")
@GetMapping("/admin/hello")
public String admin() {
return "hello admin!";
}
@ApiOperation("user Api")
@GetMapping("/user/hello")
public String user() {
return "hello user";
}
}
Swagger访问与使用
启动项目,输入http://localhost:8080/swagger-ui.html,如果能出现下面界面,说明配置成功了。
调试:点击需要访问的api列表,点击try it out!按钮,即可弹出一下页面:
配置Swagger开关1、通过enable()方法配置是否启用swagger,如果是false,swagger将不能在浏览器中访问了
@Bean
public Docket docket() {
return new Docket(documentationType.SWAGGER_2)
.apiInfo(apiInfo())
.enable(false) //配置是否启用Swagger,如果是false,在浏览器将无法访问
.select()// 通过.select()方法,去配置扫描接口,RequestHandlerSelectors配置如何扫描接口
.apis(RequestHandlerSelectors.basePackage("com.kuang.swagger.controller"))
// 配置如何通过path过滤,即这里只扫描请求以/kuang开头的接口
.paths(PathSelectors.ant("/kuang/**"))
.build();
}
动态配置
动态配置当项目处于test、dev环境时显示swagger,处于prod时不显示
@Bean
public Docket docket(Environment environment) {
// 设置要显示swagger的环境
Profiles of = Profiles.of("dev", "test");
// 判断当前是否处于该环境
// 通过 enable() 接收此参数判断是否要显示
boolean b = environment.acceptsProfiles(of);
return new Docket(documentationType.SWAGGER_2)
.apiInfo(apiInfo())
.enable(b) //配置是否启用Swagger,如果是false,在浏览器将无法访问
.select()// 通过.select()方法,去配置扫描接口,RequestHandlerSelectors配置如何扫描接口
.apis(RequestHandlerSelectors.basePackage("com.kuang.swagger.controller"))
// 配置如何通过path过滤,即这里只扫描请求以/kuang开头的接口
.paths(PathSelectors.ant("/kuang/**"))
.build();
}
可以在项目中增加一个dev的配置文件查看效果!
| 作用范围 | API | API常用参数 | 作用位置 |
|---|---|---|---|
| 协议集描述 | @Api | @Api(tags = {"tag1","tag2","..."}) | controller类 |
| 协议描述 | @ApiOperation | @ApiOperation(value = "功能描述",notes = "备注") | controller类的方法 |
| 描述返回对象的意义 | @ApiModel | @ApiModel(value="类名",description="类描述") | 返回对象类 |
| 对象属性 | @ApiModelProperty | @ApiModelProperty(value = "类属性描述",required = true,example = "属性举例",notes = "备注") | 出入参数对象的字段 |
| 非对象参数集 | @ApiImplicitParams | @ApiImplicitParams({@ApiImplicitParam(),@ApiImplicitParam(),...}) | controller的方法 |
| 非对象参数描述 | @ApiImplicitParam | @ApiImplicitParam(name = "参数名",value = "参数描述",required = true,paramType = "接口传参类型",dataType = "参数数据类型") | @ApiImplicitParams的方法里用 |
| Response集 | @ApiResponses | @ApiResponses({ @ApiResponse(),@ApiResponse(),..}) | controller的方法 |
| Response | @ApiResponse | @ApiResponse(code = 10001, message = "返回信息") | @ApiResponses里用 |
| 忽略注解 | @ApiIgnore | @ApiIgnore | 类,方法,方法参数 |
作用:用来指定接口的描述文字@ApiOperation(value = " ",notes = " ")
修饰范围:作用在类上
作用:用来对接口中具体方法做描述@ApiImplicitParams
修饰范围:作用在方法上
value:用来对接口的总体描述
notes:用来对接口的详细描述
方式一:url?id=1&user='qlh'后面参数作用:用来对接口中参数进行说明
修饰范围:作用在方法上
参数:@ApiImplicitParam数组@ApiImplicitParam
作用:修饰接口方法里面的参
修饰范围:作用方法上
参数:
- name:方法参数名称
- value:方法参数的描述
- dataType:方法参数数据类型
- defaultValue :方法参数默认值(给测试人员做测试用的)
- paramType :
默认query:对应方式一
- path:对应方式二
- body:对应方式三
@ApiOperation(value = "接口总体描述", notes = "详细描述: 方法详细描述信息")
@ApiImplicitParams({
@ApiImplicitParam(name = "username", value = "用户名", dataType = "String", defaultValue = "qlh"),
@ApiImplicitParam(name = "password", value = "密码", dataType = "String", defaultValue = "123")
})
@PostMapping("/")
public String login(String username, String password) {
return "Hello login ~";
}
方式二:url/1/2路径后 传参 在路径中获取参数
@ApiOperation(value = "接口总体描述", notes = "详细描述: 方法详细描述信息")
@ApiImplicitParams({
@ApiImplicitParam(name = "id", value = "id", dataType = "String", defaultValue = "qlh",paramType = "path"),
@ApiImplicitParam(name = "name", value = "姓名", dataType = "String", defaultValue = "123",paramType = "path")
})
@PostMapping("/index/{id}/{name}")
public String index(@PathVariable("id") String id, @PathVariable("name") String name) {
return "Hello World ~";
}
方式三:在body中传参
@ApiOperation(value = "接口总体描述", notes = "详细描述: 方法详细描述信息")
@ApiImplicitParams({
@ApiImplicitParam(name = "id", value = "id", dataType = "String", defaultValue = "xxx", paramType = "body"),
@ApiImplicitParam(name = "name", value = "姓名", dataType = "String", defaultValue = "123", paramType = "body")
})
@PostMapping("/index")
public String index(@RequestBody Map map) {
return "Hello World ~";
}
@ApiResponses
作用:用于接口的响应结果@ApiResponse
修改范围:作用在接口方法上
参数:@ApiResponse数组
@ApiIgnore作用:在ApiResponses里面对响应码以及响应内容进行设置
修饰范围:作用接口方法上
参数:
- code:响应状态码
- message:响应状态码对应的响应内容
作用:忽略类,方法,参数。(忽略的意思:在swagger-ui.html中不显示)实体类中swagger注解 @ApiModel
修改范围:作用在类,方法,参数上
作用:用来对实体类进行说明@ApiModelProperty
修饰范围:作用在类上
作用:用来对实体类中的属性进行说明
修饰范围:作用在类中的属性上
只要这个实体在请求接口的返回值上(即使是泛型),都能映射到实体项中:
1、如果没有配置分组,默认是default。通过groupName()方法即可配置分组:
@Bean
public Docket docket(Environment environment) {
return new Docket(documentationType.SWAGGER_2).apiInfo(apiInfo())
.groupName("hello") // 配置分组
// 省略配置....
}
2、重启项目查看分组
3、如何配置多个分组?配置多个分组只需要配置多个docket即可:
@Configuration
@EnableSwagger2
public class Swagger2Config {
@Bean
public Docket adminApiConfig(){
return new Docket(documentationType.SWAGGER_2)
.groupName("adminApi")
.apiInfo(adminApiInfo())
.select()
.paths(Predicates.and(PathSelectors.regex("/admin/.*")))
.build();
}
private ApiInfo adminApiInfo(){
return new ApiInfoBuilder()
.title("尚融宝后台管理系统API文档")
.description("本文档描述了尚融宝后台管理系统的各个模块的接口的调用方式")
.version("1.6")
.contact(new Contact("Helen", "http://atguigu.com", "admin@atguigu.com"))
.build();
}
@Bean
public Docket webApiConfig(){
return new Docket(documentationType.SWAGGER_2)
.groupName("webApi")
.apiInfo(webApiInfo())
.select()
.paths(Predicates.and(PathSelectors.regex("/api/.*")))
.build();
}
private ApiInfo webApiInfo(){
return new ApiInfoBuilder()
.title("尚融宝网站API文档")
.description("本文档描述了尚融宝网站各个模块的接口的调用方式")
.version("1.6")
.contact(new Contact("Helen", "http://atguigu.com", "admin@atguigu.com"))
.build();
}
}
4、重启项目查看即可
拓展:其他皮肤bootstrap-ui 访问 http://localhost:8080/doc.html
com.github.xiaoymin swagger-bootstrap-ui 1.9.1
Layui-ui 访问 http://localhost:8080/docs.html
com.github.caspar-chen swagger-ui-layer 1.1.3
mg-ui 访问 http://localhost:8080/document.html
com.zyplayer swagger-mg-ui 1.0.6



