Spring Boot 集成 Swagger 生成 RESTful API 文档

时间:2022-02-22 15:14:20

原文链接:

简介

Swagger 官网是这么描述它的:The Best APIs are Built with Swagger Tools

Swagger 是一套基于 OpenAPI 规范构建的开源工具,可以帮助我们设计、构建、记录以及使用 Rest API。Swagger 主要包含了以下三个部分:

  1. Swagger Editor:基于浏览器的编辑器,我们可以使用它编写我们 OpenAPI 规范。
  2. Swagger UI:它会将我们编写的 OpenAPI 规范呈现为交互式的 API 文档,后文我将使用浏览器来查看并且操作我们的 Rest API。
  3. Swagger Codegen:它可以通过为 OpenAPI(以前称为 Swagger)规范定义的任何 API 生成服务器存根和客户端 SDK 来简化构建过程。

Spring Boot 使得开发 RESTful 服务变得简单。那么编写 Spring Boot 接口,为何要用 Swagger 呢?

  • 代码改变,文档就会改变。只需要少量的注释,Swagger 就可以根据代码自动生成 API 文档。
  • Swagger UI 是一份交互式的 API 文档,可以直接在 Web 界面调用 API。这里有一份 Swagger UI 的 Live Demo,看看官方是怎么写 RESTful API 的。

添加依赖

pom.xml 引入 Swagger 相关的依赖:

<!-- 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 的版本,因此还需要添加:

<swagger.version>2.9.2</swagger.version>

依赖说明:

  • springfox-swagger2 Swagger 的 Java 实现
  • springfox-swagger-ui Swagger UI 页面的依赖

Swagger 配置类

使用注解 @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;
}
}

说明:

  • @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

编写控制器类——Controller 类

我们先介绍一下在用 Swagger 时的常用注解:

  • @API 类的注解,可以给控制器增加描述和标签信息。用在请求的类上,代表了这个类是 Swagger 的资源
    • tags:控制器标签,对该类进行「分类」,参数是个字符串数组,如果配置了多个值,会在多个分类中看到;
    • value:该参数没什么意义,在 UI 界面上并不显示,可不用配置
  • @ApiModel 类注解,对 API 涉及的对象做描述,可用于响应实体类,说明实体作用
    • value Model 展示时的名称,默认是 实体类的名称,比如 UserEntity
    • description 实体类的描述

Spring Boot 集成 Swagger 生成 RESTful API 文档

类成员变量的的注解:

  • @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:

Spring Boot 集成 Swagger 生成 RESTful API 文档

页面上还会有一个 Models 的分类。Swagger UI 会根据我们在实体上使用的 @ApiModel@ApiModelProperty 注解来自动补充实体以及其属性的描述和备注。

Spring Boot 集成 Swagger 生成 RESTful API 文档

示例代码

One More Thing

Web API 的风格

开发 API,先了解一下有哪些 Web API 的风格吧:

  • RPC:RPC 面向过程,RPC 形式的 API 组织形态是类和方法,API 的命名往往是一个动词,比如 GetUserInfo,CreateUser;
  • REST:REST 面向资源,也是下文将要介绍的一种 API 风格;
  • GraphQL:就是面向数据查询,采用GraphQL,甚至不需要有任何的接口文档,在定义了Schema之后,服务端实现Schema,客户端可以查看Schema,然后构建出自己需要的查询请求来获得自己需要的数据

REST

上文提到了 RESTful API 的概念,我觉得,不如趁机了解一下。因为在实际的项目中发现,并不是每个 Spring Boot 的开发人员都能意识到开发的 API 要尽量符合 RESTful 规则的。REST 实际上只是一种设计风格,它并不是标准。

术语:

  • Endpoint 终点,可以理解为路径,表示 API 的具体网址。
  • API(Application Programming Interface),应用程序编程接口
  • RESTRepresentational State Transfer 的缩写。如果一个架构符合 REST 原则,就称它为 RESTful 架构。RESTful API 就是 REST 风格的 API
    • Resource:资源,即数据。
    • Representational:某种表现形式,比如用 JSON,XML,JPEG 等;
    • State Transfer:状态变化。通过 HTTP 动词实现

在 RESTful 架构中,每个网址代表一种资源(resource),所以网址中不能有动词,只能有名词,而且所用的名词往往与数据库的表格名对应。

资源的操作

RESTful 的核心思想就是,客户端发出的数据操作指令都是"动词 + 宾语"的结构。比如,GET /articles 这个命令,GET 是动词,/articles 是宾语。

对于资源的具体操作类型,由 HTTP 动词表示(括号里是对应的 SQL 命令):

  • GET(SELECT):从服务器取出资源(一项或多项)。
  • POST(CREATE):在服务器新建一个资源。
  • PUT(UPDATE):在服务器更新资源(客户端提供改变后的完整资源)。
  • PATCH(UPDATE):在服务器更新资源(客户端提供改变的属性)。
  • DELETE(DELETE):从服务器删除资源

还有两个不常用的 HTTP 动词:

  • HEAD:获取资源的元数据。
  • OPTIONS:获取信息,关于资源的哪些属性是客户端可以改变的

知乎上的一个回答,我觉得很精辟:

  • 看 Url 就知道要什么
  • 看 http method 就知道干什么
  • 看 http status code 就知道结果如何

一位答主给出的示例:

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 删除一个小狗狗

信息过滤 Filtering

如果记录数量很多,服务器不可能都将它们返回给用户。API 应该提供参数,过滤返回结果

  • ?limit=10:指定返回记录的数量
  • ?offset=10:指定返回记录的开始位置。
  • ?page=2&per_page=100:指定第几页,以及每页的记录数

参考

API 介绍

欢迎关注个人公众号 「iPlayMichael」

Spring Boot 集成 Swagger 生成 RESTful API 文档

Spring Boot 集成 Swagger 生成 RESTful API 文档的更多相关文章

  1. Spring Boot 集成Swagger2生成RESTful API文档

    Swagger2可以在写代码的同时生成对应的RESTful API文档,方便开发人员参考,另外Swagger2也提供了强大的页面测试功能来调试每个RESTful API. 使用Spring Boot可 ...

  2. Spring Boot学习笔记 - 整合Swagger2自动生成RESTful API文档

    1.添加Swagger2依赖 在pom.xml中加入Swagger2的依赖 <!--swagger2--> <dependency> <groupId>io.spr ...

  3. Spring Boot中使用Swagger2构建API文档

    程序员都很希望别人能写技术文档,自己却很不愿意写文档.因为接口数量繁多,并且充满业务细节,写文档需要花大量的时间去处理格式排版,代码修改后还需要同步修改文档,经常因为项目时间紧等原因导致文档滞后于代码 ...

  4. springboot集成swagger2构建RESTful API文档

    在开发过程中,有时候我们需要不停的测试接口,自测,或者交由测试测试接口,我们需要构建一个文档,都是单独写,太麻烦了,现在使用springboot集成swagger2来构建RESTful API文档,可 ...

  5. 使用Swagger2Markup归档swagger生成的API文档

    文章出处: http://blog.didispace.com/swagger2markup-asciidoc/ 说明 项目中使用Swagger之后,我们能够很轻松的管理API文档,并非常简单的模拟接 ...

  6. Golang使用swaggo自动生成Restful API文档

    #关于Swaggo 相信很多程序猿和我一样不喜欢写API文档.写代码多舒服,写文档不仅要花费大量的时间,有时候还不能做到面面具全.但API文档是必不可少的,相信其重要性就不用我说了,一份含糊的文档甚至 ...

  7. Spring Boot 集成 Swagger生成接口文档

    目的: Swagger是什么 Swagger的优点 Swagger的使用 Swagger是什么 官网(https://swagger.io/) Swagger 是一个规范和完整的框架,用于生成.描述. ...

  8. Spring Boot中使用Swagger2生成RESTful API文档(转)

    效果如下图所示: 添加Swagger2依赖 在pom.xml中加入Swagger2的依赖 <!-- https://mvnrepository.com/artifact/io.springfox ...

  9. 如何生成RestFul Api文档

    Web API文档工具列表Swagger ——Swagger框架可以通过代码生成漂亮的在线API,甚至可以提供运行示例.支持Scala.Java.Javascript.Ruby.PHP甚至 Actio ...

随机推荐

  1. ASP&period;NET MVC5&plus;EF6&plus;EasyUI 后台管理系统(80)-*桌面

    系列目录 前言 这次我们来做一个有趣的事情,有朋友跟做了很远,找我要*桌面的代码,这次我们将演示*桌面的代码. *桌面:用户可以随意增删改桌面的布局.个数(只留自己需要看到的数据),这次纯属Ea ...

  2. ASP&period;NET Web&period;config

    分析: .NET Web 应用程序的配置信息(如最常用的设置ASP.Net Web 应用程序的身份验证方式),它可以出现在应用程序的每一个目录中.当你通过VB.NET新 建 一个Web应用程序后,默认 ...

  3. 微信小程序-视图数据绑定

    数据绑定 在逻辑层设置数据例如: Page({ data: { message: 'Hello MINA!' } })//设置了一个属性,名称是message 值为Hello MINA! 在视图显示数 ...

  4. bcopy函数

    函数原型:void bcopy(const  void  *src,  void  *dest,  int  n) 头文件:#include <string.h> 函数功能:将src指针指 ...

  5. SQL语句执行顺寻

    SQL语句执行的时候是有一定顺序的.理解这个顺序对SQL的使用和学习有很大的帮助. 1.from 先选择一个表,或者说源头,构成一个结果集. 2.where 然后用where对结果集进行筛选.筛选出需 ...

  6. 队爷的Au Plan CH Round &num;59 - OrzCC杯NOIP模拟赛day1

    题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的Au%20Plan 题解:看了题之后觉得肯定是DP ...

  7. Python Moment&period;js api

    moment.js(js date)日期格式化处理插件强大,官方网站:http://momentjs.com/你也可以查看官方网站E文原版moment.js api.当前日期格式化 moment(). ...

  8. Collection与Collections,Array与Arrays的区别

    Collection 和 Collections的区别 Collection 在Java.util下的一个接口,它是各种集合结构的父接口.继承与他的接口主要有Set 和List. Collection ...

  9. 软件工程网络15个人作业4(201521123010徐璐琳)——alpha阶段个人总结

    一.个人总结 1. 总结自己的alpha 过程: 经过了两周的ALPHA阶段,在这之中学习到了很多,因为最开始其实是有抱着一种应付的.将就着的心理去做这个小程序,但是在完成项目的过程中,有老师和助教一 ...

  10. Intellij IDEA创建maven项目无java文件问题

    在idea开发工具中创建工程时,点击右键没有创建包.接口.java类的提示, 如图: 解决之前的项目目录为: 针对这种情况,对idea开发工具做以下设置. 选择File->Project Str ...