0-编辑历史
2023-10-13 10:27 , springdoc-openapi v2.2.0 , 这篇文章是我学习记录的汇总,仅供参考
宜朝西编程 可以触摸的痛苦就是肚子都饿扁了,一摸还是有一坨肉
1-参考资料
chatgpt
springdoc: springdoc.org/
OpenAPI Specification: swagger.io/docs/specif…
项目基础: juejin.cn/post/728896…
2-RESTful APIs
REST(Representational State Transfer)是一种设计网络应用程序的架构风格。RESTful APIs(RESTful Application Programming Interfaces)是基于REST原则的API设计,用于在客户端和服务器之间进行通信。
RESTful APIs 使用标准的HTTP方法(如GET、POST、PUT、DELETE)来执行对资源的操作,以及使用URL(统一资源定位符)来标识和定位资源。它通过提供一组简单而统一的规则,使得不同系统之间可以通过HTTP协议进行数据交互。
以下是 REST APIs 的一些核心特点:
资源(Resources):RESTful APIs 将应用程序的数据和功能抽象为资源,并使用唯一的URL(统一资源定位符)来标识每个资源。例如,一个博客文章可以表示为 /articles/{id} 的 URL。
HTTP 方法(HTTP Methods):RESTful APIs 使用标准的 HTTP 方法来定义对资源的操作。常见的HTTP方法包括 GET(获取资源)、POST(创建资源)、PUT(更新资源)和 DELETE(删除资源)。
表示层(Representation):RESTful APIs 通过表示层来传递和处理资源的状态。在传输过程中,可以使用各种表示格式,如 JSON、XML、HTML等。客户端和服务器之间的数据交互通常使用 JSON 格式。
无状态(Stateless):RESTful APIs 是无状态的,即在每个请求之间不保留任何会话或状态信息。每个请求都应该包含足够的信息来完全描述所需的操作。
通过使用 RESTful APIs,可以提供一种灵活、可扩展且易于理解的方式进行系统间通信。它促进了解耦和模块化的架构设计,并提供了统一的接口来访问和操作资源。因此,RESTful APIs 在现代的 Web 开发中被广泛应用,成为构建可靠和可伸缩的应用程序的常用方法。
3-OpenAPI Specification
OpenAPI Specification (formerly Swagger Specification) is an API description format for REST APIs.
OpenAPI 规范(OpenAPI Specification)是一种用于描述和定义 RESTful Web Services API 的规范。它提供了一套结构化的规则和约定,以规范和标准化 API 的设计、文档和交互方式。
OpenAPI 规范使用 JSON 或 YAML 格式编写,定义了 API 的各个方面,包括资源、操作、参数、响应、认证、版本管理等等。它提供了一种统一的标准,使得开发者和工具可以根据规范自动生成文档、进行代码生成、执行自动化测试等操作。
通过 OpenAPI 规范,可以实现以下功能:
-
设计API:通过定义资源、操作、参数和响应等,可以清晰地设计和建模 API 的结构和行为。
-
自动生成文档:基于 OpenAPI 规范,可以自动生成具有交互式界面的 API 文档,其中包括了 API 的详细信息、可用的操作、参数说明、示例请求和响应等。
-
代码生成:利用 OpenAPI 规范,可以生成客户端和服务器端的代码,以便快速启动开发,并确保接口定义的一致性。
-
自动化测试:使用 OpenAPI 规范,可以自动生成 API 的测试用例,从而简化测试工作并提高测试覆盖率。
OpenAPI 规范不仅能够帮助开发者更好地设计和理解 API,还能提供一种通用的方式来描述和交互 API。它的出现使得 API 的设计和管理更加标准化和规范化,从而提高开发效率、降低沟通成本,并促进了 API 生态系统的发展。
4-Swagger
Swagger 是一组开源工具和规范,用于设计、构建、文档化和使用 RESTful Web Services API。它提供了一种简单且强大的方式来描述和定义 API,使得开发者能够更轻松地创建和管理 API。
主要组件和功能包括:
Swagger Editor:一个可视化的编辑器,用于编写和编辑符合 OpenAPI 规范的 API 描述文档。可以直接在 Swagger Editor 中编写 OpenAPI 规范的 YAML 或 JSON 文件,并实时查看 API 文档的预览效果。
Swagger UI:一个动态的交互式文档生成工具,用于自动生成漂亮的、可浏览的 API 文档。通过 Swagger UI,开发者可以以用户友好的方式浏览 API 的资源、操作、参数等信息,并通过界面进行 API 的测试和调试。
Swagger Codegen:一个代码生成器,根据 API 描述文档自动生成客户端和服务器端的代码。开发者可以选择使用不同的编程语言和框架,生成符合规范的代码,从而快速集成和使用 API。
SwaggerHub:一个云端的 API 设计和文档平台,用于协作开发和管理 API。开发者可以在 SwaggerHub 上创建和托管 API 描述文档,并与团队成员共享和协作编辑。同时,SwaggerHub 还提供了集成工具和其他高级功能,以简化 API 的设计、测试和部署过程。
总体而言,Swagger 提供了一套完整的工具链,帮助开发者更好地设计、构建和文档化 RESTful Web Services API。它的目标是提供一种统一的方式来描述和使用 API,从而促进 API 的可视化、可测试性和可交互性,并加速 API 的开发和集成过程。
5-springdoc
springdoc 是一个用于生成 OpenAPI(以前称为 Swagger)规范的库,专门针对基于 Spring 框架构建的 RESTful Web Services API。它提供了一种方便且易于集成的方式,将 API 的注解和配置转换为符合 OpenAPI 规范的文档。
springdoc 主要功能和特点包括:
自动生成 API 文档:基于注解驱动的方式,springdoc 可以自动扫描 Spring MVC 控制器和相关的注解,并根据这些注解生成对应的 API 文档。开发者只需要在代码中添加相应的注解,就可以自动生成具有详细描述、参数说明、响应信息等的 API 文档。
支持 OpenAPI 规范:springdoc 严格遵循 OpenAPI 规范(原 Swagger 规范),并支持最新的 OpenAPI 3.x 版本。它能够生成符合规范的 API 描述文件,用于定义 API 的结构、操作、参数、响应等信息。
集成 Spring Boot:springdoc 是为 Spring Boot 框架设计的,可以与 Spring Boot 应用程序无缝集成。通过简单的配置,开发者可以轻松地将 springdoc 引入到现有的 Spring Boot 项目中,并自动生成 API 文档。
与 Swagger UI 集成:springdoc 提供了与 Swagger UI 的集成,可以直接在浏览器中查看和测试生成的 API 文档。通过配置,开发者可以轻松地将 Swagger UI 集成到应用程序中,以实现可交互的 API 文档展示和测试。
总之,springdoc 是一个方便的库,可以帮助开发者快速生成符合 OpenAPI 规范的 API 文档。它与 Spring Boot 紧密集成,并支持最新的 OpenAPI 3.x 版本,为基于 Spring 框架的 API 提供了简单、可靠的文档生成解决方案。
springdoc-openapijava library supportsOpenAPI 3、Swagger-ui
6-从 Swagger 1.0 到 Swagger 2.0 到最新的 OpenAPI 3.0
OpenAPI Specification(之前被称为 Swagger Specification)是一种用于描述 REST APIs 的规范,提供了一种标准化的方法来定义和文档化 API。
下面是 OpenAPI Specification 的发展历程:
Swagger 1.0:Swagger 最初由 Reverb Technologies 创建,在2011年发布了第一个版本(Swagger 1.0)。Swagger 1.0 采用了 JSON 或 YAML 格式来定义 API,包含了一些基本的元素,例如 API 的路径、HTTP 方法、参数等。
Swagger 2.0:在 Swagger 1.0 的基础上,Swagger 2.0 将规范扩展为了一个更为全面的描述语言,支持更多的 API 元素。Swagger 2.0 发布于2014年,包括了更完整的数据类型、请求体及响应的定义方式、OAuth2 支持等改进,同时 Swagger 2.0 也开始使用 "OpenAPI Specification" 这个名称。
OpenAPI 3.0:OpenAPI 3.0 发布于2017年,是对 Swagger 2.0 的重大更新。OpenAPI 3.0 在 Swagger 2.0 的基础上,重新设计了规范,增加了许多新功能和改进。例如,增加了对不同编程语言的所需的 OpenAPI 代码生成支持、新增了 Webhooks 以支持事件驱动的 API 和纯 JSON 的描述模型等。
总之,OpenAPI Specification 的发展历程经历了从 Swagger 1.0 到 Swagger 2.0 到最新的 OpenAPI 3.0 的变化,规范越来越完善和健全,提供了更多的优秀特性和选择。现在,OpenAPI Specification 已成为 REST API 设计和开发的行业标准之一,被广泛使用和支持。
7-添加springdoc-openapi依赖
For the integration between spring-boot and swagger-ui, add the library to the list of your project dependencies (No additional configuration is needed)
maven:
<!-- https://mvnrepository.com/artifact/org.springdoc/springdoc-openapi-starter-webmvc-ui -->
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>2.2.0</version>
</dependency>
gradle:
// https://mvnrepository.com/artifact/org.springdoc/springdoc-openapi-starter-webmvc-ui
implementation group: 'org.springdoc', name: 'springdoc-openapi-starter-webmvc-ui', version: '2.2.0'
This will automatically deploy swagger-ui to a spring-boot application:
-
Documentation will be available in
HTMLformat, using the official swagger-ui jars -
The
Swagger UIpage will then be available athttp://server:port/context-path/swagger-ui.htmland the OpenAPI description will be available at the following url for json format:http://server:port/context-path/v3/api-docs-
server: The server name or IP
-
port: The server port
-
context-path: The context path of the application
-
-
Documentation can be available in
yamlformat as well, on the following path :/v3/api-docs.yaml
8-custom path
For custom path of the swagger documentation in HTML format, add a custom springdoc property, in your spring-boot configuration file: .
# swagger-ui custom path
springdoc.swagger-ui.path=/swagger-ui.html
springdoc:
swagger-ui:
path: /swagger-ui/index.html
9-Springdoc-openapi Properties
9-1-springdoc-openapi core properties
2023-10-13 11:33,项目中常用的 springdoc-openapi 属性
Parameter name: springdoc.api-docs.path
Default Value: /v3/api-docs
Description: String, For custom path of the OpenAPI documentation in Json format.
Parameter name: springdoc.api-docs.enabled
Default Value: true
Description: Boolean. To disable the springdoc-openapi endpoint (/v3/api-docs by default).
Parameter name: springdoc.packages-to-scan
Default Value: *
Description: List of Strings.The list of packages to scan (comma separated)
Parameter name: springdoc.cache.disabled
Default Value: false
Description: Boolean. To disable the springdoc-openapi cache of the calculated OpenAPI.
9-2-swagger-ui properties
Parameter name: springdoc.swagger-ui.path
Default Value: /swagger-ui.html
Description: String, For custom path of the swagger-ui HTML documentation.
Parameter name: springdoc.swagger-ui.enabled
Default Value: true
Description: Boolean. To disable the swagger-ui endpoint (/swagger-ui.html by default).
Parameter name: springdoc.swagger-ui.tagsSorter
Default Value:
Description: Function=(a ⇒ a). Apply a sort to the tag list of each API. It can be 'alpha' (sort by paths alphanumerically) or a function see Array.prototype.sort() to learn how to write a sort function). Two tag name strings are passed to the sorter for each pass. Default is the order determined by Swagger UI.
9-3-spring-boot configuration file
2023-10-13 11:39,给大家看一下我的示例, 如上所述 springdoc.api-docs.path 的默认值就是 /v3/api-docs
springdoc:
api-docs:
enabled: true
path: /v3/api-docs
version: openapi_3_0
swagger-ui:
path: /swagger-ui/index.html
tagsSorter: alpha
use-root-path: true
cache:
disabled: true
10-启动类入口修改
对启动类作如下修改
package com.example.lkcoffee;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.core.env.Environment;
import java.net.InetAddress;
import java.net.UnknownHostException;
/**
* @author
*/
@SpringBootApplication
public class LkcoffeeApplication {
private static final Logger logger = LoggerFactory.getLogger(LkcoffeeApplication.class);
/**
* Swagger地址:http://localhost:8080/swagger-ui/index.html#/
* 参考资料:https://dzone.com/articles/openapi-3-documentation-with-spring-boot
* @param args args
*/
public static void main(String[] args) throws UnknownHostException {
ApplicationContext applicationContext = SpringApplication.run(LkcoffeeApplication.class, args);
Environment environment = applicationContext.getEnvironment();
logger.info("\n---------------------------------------------lkcoffee-----------------------------------------------------------------------\n" +
"应用 '{}' 运行成功! \n" +
"Swagger-UI-Interface 访问连接: http://{}:{}{}{} \n" +
"API-Docs 访问连接: http://{}:{}{}{} \n" +
"--------------------------------------------------------------------------------------------------------------------",
environment.getProperty("spring.application.name"),
InetAddress.getLocalHost().getHostAddress(),
environment.getProperty("server.port", "8080"),
environment.getProperty("server.servlet.context-path", ""),
environment.getProperty("springdoc.swagger-ui.path", "/swagger-ui/index.html"),
InetAddress.getLocalHost().getHostAddress(),
environment.getProperty("server.port", "8080"),
environment.getProperty("server.servlet.context-path", ""),
environment.getProperty("springdoc.api-docs.path", "/v3/api-docs")
);
}
}
11-代码修改
11-1-替换注解
根据 Migrating from SpringFox 章节
Swagger 3 引入了一些新的注解,并对原有的注解进行了调整。下面是注解的使用场景发生变化的详细说明:
-
@Api→@Tag:Swagger 3 中将@Api注解替换为@Tag注解,用于对 API 接口进行分组和标记。 -
@ApiIgnore→@Parameter(hidden = true)或@Operation(hidden = true)或@Hidden:Swagger 3 中取消了@ApiIgnore注解,取而代之的是通过其他注解来实现隐藏某个参数或操作。可以使用@Parameter(hidden = true)、@Operation(hidden = true)或@Hidden注解来实现隐藏功能。 -
@ApiImplicitParam→@Parameter:Swagger 3 中将@ApiImplicitParam注解替换为@Parameter注解,用于描述接口参数。 -
@ApiImplicitParams→@Parameters:Swagger 3 中将@ApiImplicitParams注解替换为@Parameters注解,用于对多个参数进行描述。 -
@ApiModel→@Schema:Swagger 3 中将@ApiModel注解替换为@Schema注解,用于描述数据模型。 -
@ApiModelProperty(hidden = true)→@Schema(accessMode = READ_ONLY):Swagger 3 中取消了@ApiModelProperty(hidden = true)注解,取而代之的是使用@Schema(accessMode = READ_ONLY)注解实现隐藏某个属性。 -
@ApiModelProperty→@Schema:Swagger 3 中将@ApiModelProperty注解替换为@Schema注解,用于描述属性。 -
@ApiOperation(value = "foo", notes = "bar")→@Operation(summary = "foo", description = "bar"):Swagger 3 中将@ApiOperation注解替换为@Operation注解,用于对接口进行详细描述。 -
@ApiParam→@Parameter:Swagger 3 中将@ApiParam注解替换为@Parameter注解,用于描述接口参数。 -
@ApiResponse(code = 404, message = "foo")→@ApiResponse(responseCode = "404", description = "foo"):Swagger 3 中将@ApiResponse注解中的code属性替换为responseCode属性,用于描述响应结果。
11-2-修改后的控制器层代码
package com.example.lkcoffee.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.example.lkcoffee.persistence.entity.Coffee;
import com.example.lkcoffee.search.CoffeeSearchCriteria;
import com.example.lkcoffee.service.CoffeeService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;
/**
* The type Coffee controller.
*
* @author yang.jianming3
* @version 1.0
* @since 2023 /10/11 10:09
*/
@Tag(name = "lkCoffee API")
@RestController
@RequestMapping("/coffee")
public class CoffeeController {
@Autowired
private CoffeeService coffeeService;
/**
* Gets coffee page.
*
* @param rating the rating
* @param pageNumber the page number
* @param pageSize the page size
* @return the user page
*/
@Operation(summary = "按评分获取咖啡分页列表")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "成功获取咖啡分页列表"),
@ApiResponse(responseCode = "500", description = "服务器内部错误")
})
@GetMapping("/page")
public ResponseEntity<IPage<Coffee>> getCoffeePage(
@Parameter(description = "咖啡评分") @RequestParam float rating,
@Parameter(description = "页码,默认为1") @RequestParam(defaultValue = "1") Long pageNumber,
@Parameter(description = "每页记录数,默认为10") @RequestParam(defaultValue = "10") Long pageSize
) {
CoffeeSearchCriteria coffeeSearchCriteria = new CoffeeSearchCriteria();
coffeeSearchCriteria.setRating(rating);
coffeeSearchCriteria.setCurrentPage(pageNumber);
coffeeSearchCriteria.setPageSize(pageSize);
IPage<Coffee> coffeeIPage = coffeeService.getCofeePage(coffeeSearchCriteria);
return ResponseEntity.ok(coffeeIPage);
}
/**
* Gets coffee list.
*
* @return the coffee list
*/
@Operation(summary = "获取咖啡列表")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "成功获取咖啡列表"),
@ApiResponse(responseCode = "500", description = "服务器内部错误")
})
@GetMapping("/list")
public ResponseEntity<List<Coffee>> getCoffeeList() {
List<Coffee> coffeeList = coffeeService.list();
return ResponseEntity.ok(coffeeList);
}
/**
* Gets coffee by id.
*
* @param id the id
* @return the coffee by id
*/
@Operation(summary = "根据 ID 获取咖啡")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "成功获取咖啡"),
@ApiResponse(responseCode = "500", description = "服务器内部错误")
})
@GetMapping("/{id}")
public ResponseEntity<Coffee> getCoffeeById(
@Parameter(description = "咖啡 ID") @PathVariable Integer id) {
Coffee coffee = coffeeService.getById(id);
return ResponseEntity.ok(coffee);
}
/**
* Save coffee response entity.
*
* @param coffee the coffee
* @return the response entity
*/
@Operation(summary = "保存咖啡")
@ApiResponses(value = {
@ApiResponse(responseCode = "201", description = "成功保存咖啡"),
@ApiResponse(responseCode = "500", description = "服务器内部错误")
})
@PostMapping("/save")
public ResponseEntity<Void> saveCoffee(@RequestBody Coffee coffee) {
coffeeService.save(coffee);
return ResponseEntity.status(HttpStatus.CREATED).build();
}
/**
* Update coffee by id response entity.
*
* @param coffee the coffee
* @return the response entity
*/
@Operation(summary = "更新咖啡")
@ApiResponses(value = {
@ApiResponse(responseCode = "204", description = "成功更新咖啡"),
@ApiResponse(responseCode = "500", description = "服务器内部错误")
})
@PutMapping("/update")
public ResponseEntity<Void> updateCoffeeById(@RequestBody Coffee coffee) {
coffeeService.updateById(coffee);
return ResponseEntity.noContent().build();
}
/**
* Delete coffee by id response entity.
*
* @param id the id
* @return the response entity
*/
@Operation(summary = "根据 ID 删除咖啡")
@ApiResponses(value = {
@ApiResponse(responseCode = "204", description = "成功删除咖啡"),
@ApiResponse(responseCode = "500", description = "服务器内部错误")
})
@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteCoffeeById(
@Parameter(description = "咖啡 ID") @PathVariable Integer id
) {
coffeeService.removeById(id);
return ResponseEntity.noContent().build();
}
}
11-3-实体类修改
可以在实体类加上 @Schema(description = "coffee model") 注解,描述数据模型
12-添加 OpenAPI Bean
bean of OpenAPI type.
在 Springdoc 中,OpenAPI 类是一个代表 OpenAPI 规范的对象模型,用于描述和定义 API 文档。
OpenAPI 对象包含了 API 的基本信息,如标题、描述、版本号等,还包括了 API 的路径、操作、参数、响应等详细信息。它可以用于生成符合 OpenAPI 规范的 API 文档,这些文档可以用于 API 的文档化、交流和测试。
OpenAPI 类有如下字段
private String title = null;
private String description = null;
private String termsOfService = null;
private Contact contact = null;
private License license = null;
private String version = null;
private java.util.Map<String, Object> extensions = null;
在 Springdoc 中,您可以创建一个 OpenAPI 对象的实例,并通过配置该实例来自定义 API 文档。您可以添加全局参数、安全定义、服务器信息等到 OpenAPI 对象中,以满足您的特定需求。
OpenAPI 对象可以与 Spring Boot 应用程序集成,以便自动化生成 OpenAPI 文档。它与 Springdoc 提供的其他组件(如 Docket、GroupedOpenApi)一起使用,以便更好地管理和生成 API 文档。
package com.example.lkcoffee.config;
import io.swagger.v3.oas.models.ExternalDocumentation;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.info.License;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* The type Swagger config.
*
* @author yang.jianming3
* @version 1.0
* @since 2023 /10/13 13:14
*/
@Configuration
public class SwaggerConfig {
/**
* Lk coffee open api.
*
* @return the open api
*/
@Bean
public OpenAPI lkCoffeeOpenAPI() {
return new OpenAPI()
.info(new Info().title("lkCoffee API")
.description("lkCoffee application")
.version("v0.0.1")
.license(new License().name("Apache 2.0").url("http://springdoc.org")))
.externalDocs(new ExternalDocumentation()
.description("lkCoffee Wiki Documentation")
.url("http://springdoc.org"));
}
}
13-springfox vs springdoc
OAS 3 was released in July 2017, and there was no release of springfox to support OAS 3.
springfox covers for the moment only swagger 2 integration with Spring Boot. The latest release date is June 2018. So, in terms of maintenance there is a big lack of support lately.
The biggest difference with springfox, is that springdoc integrate new features not covered by springfox:
The integration between Spring Boot and OpenAPI 3 standard.
springdoc rely on swagger-annotations and swagger-ui only official libraries.
14-Summary
这篇文章主要是介绍 RESTful APIs 、 OpenAPI Specification 、Swagger 、Swagger-UI 、Springdoc 、Springfox 这些概念
RESTful APIs 是一种设计原则,OpenAPI Specification 和 Swagger 是用于描述和文档化这种 API 设计的标准和工具,而 Springdoc 和 Springfox 是用于在 Spring Boot 应用程序中生成符合 OpenAPI Specification 标准的 API 文档的库。最后,Swagger-UI 则是一个用于直观展示 API 文档并在浏览器中调试 API 的 Web 界面。
并介绍如何在一个 Spring Boot 项目中快速集成 springdoc 提供对 Swagger-UI 的支持。