微服务构建:Spring Boot 与 Vert.x 的 API 文档及应用实践
1. Swagger 文档与 OpenAPI
在微服务架构中,会构建大量的 API 用于数据暴露和服务间通信,因此对 API 进行文档记录十分必要。为规范 REST API 的描述,开放 API 倡议(OAI)应运而生,其目的是创建和发展一个与供应商无关的标准描述格式。SmartBear 公司将 Swagger 规范捐赠给 OAI,使其成为 API 文档的事实标准。
Spring 本身没有内置的 API 文档生成机制,但借助 SpringFox 等开源框架可以轻松实现。SpringFox 能为使用 Spring 框架编写的 JSON API 自动生成可读的规范。
1.1 集成 Swagger 和 SpringFox
要集成 Swagger 和 SpringFox,需在 Maven 的 pom.xml 文件中添加相关依赖:
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
然后在 Spring Boot 配置中创建 Docket bean 以集成 Swagger 2:
@Configuration
@EnableSwagger2
public class SwaggerConfig extends WebMvcConfigurationSupport {
@Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2).select()
.apis(RequestHandlerSelectors.basePackage(
"com.packtpub.springboot.footballplayermicroservice.controller"))
.paths(PathSelectors.any())
.build();
}
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("swagger-ui.html")
.addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/");
}
}
这里使用
@EnableSwagger2
注解启用 Swagger 支持,
api
方法通过字符串谓词过滤要记录的控制器和方法。
运行应用程序:
$ mvn spring-boot:run
通过访问
http://localhost:8080/v2/api-docs
可获取 API 文档的 JSON 表示。以下是部分示例:
{
"swagger":"2.0",
"info":{
"description":"Api Documentation",
"version":"1.0",
"title":"Api Documentation",
"termsOfService":"urn:tos",
"contact":{},
"license":{
"name":"Apache 2.0",
"url":"http://www.apache.org/licenses/LICENSE-2.0"
}
},
"host":"localhost:8080",
"basePath":"/",
"tags":[
{
"name":"football-player-rest-controller",
"description":"Football Player REST Controller"
}
],
"paths":{
"/footballplayer":{
"get":{
"tags":[
"football-player-rest-controller"
],
"summary":"findAll",
"operationId":"findAllUsingGET",
"produces":[
"application/json"
],
"responses":{
"200":{
"description":"OK",
"schema":{
"$ref":"#/definitions/Iterable«FootballPlayer»"
}
},
"401":{
"description":"Unauthorized"
},
"403":{
"description":"Forbidden"
},
"404":{
"description":"Not Found"
}
},
"deprecated":false
}
},
"/footballplayer/delete/{id}":{
"delete":{
"tags":[
"football-player-rest-controller"
],
"summary":"delete",
"operationId":"deleteUsingDELETE",
"produces":[
"application/json"
],
"parameters":[
{
"name":"id",
"in":"path",
"description":"id",
"required":true,
"type":"integer",
"format":"int32"
}
],
"responses":{
"200":{
"description":"OK"
},
"204":{
"description":"No Content"
},
"401":{
"description":"Unauthorized"
},
"403":{
"description":"Forbidden"
}
},
"deprecated":false
}
}
}
}
1.2 使用 Swagger UI
为获取可读、结构化的文档,可使用 Swagger UI。访问
http://localhost:8080/swagger-ui.html
即可查看生成的文档。
在使用前,可自定义控制台的头部部分,向用户解释 UI 中描述的 API 文档类型。在
SwaggerConfig
类中添加元数据 API 信息:
private ApiInfo metaData() {
return new ApiInfoBuilder()
.title("Spring Boot REST API")
.description("\"Spring Boot REST API for Football Player Microservice\"")
.version("1.0.0")
.license("Apache License Version 2.0")
.licenseUrl("https://www.apache.org/licenses/LICENSE-2.0\"")
.contact(new Contact("Mauro Vocale",
"https://github.com/Hands-on-MSA-JakartaEE",
"mauro.vocale@gmail.com"))
.build();
}
并在
SwaggerConfig
类的
api
方法的管道构建器中添加对
metaData
方法的调用。重新运行应用程序:
$ mvn spring-boot:run
此时可看到与构建和暴露 API 的组织相关的更详细信息。
1.3 自定义控制器类
为描述操作端点的目的,可使用
@ApiOperation
注解描述端点及其响应类型,示例如下:
@ApiOperation(value = "View all available football players", response = Iterable.class)
@ApiResponses(value = {
@ApiResponse(code = 200, message = "Successfully retrieved list"),
@ApiResponse(code = 404, message = "The resource you were trying to reach is not found")
})
@RequestMapping(method = RequestMethod.GET, produces = "application/json")
public Iterable<FootballPlayer> findAll() {
return service.findAll();
}
@ApiOperation(value = "Add a football player")
@RequestMapping(value = "/save", method = RequestMethod.POST, produces = "application/json")
public FootballPlayer save(@RequestBody FootballPlayer entity) {
return service.save(entity);
}
@ApiOperation(value = "Update a football player")
@RequestMapping(value = "/update/{id}", method = RequestMethod.PUT, produces = "application/json")
public FootballPlayer edit(@PathVariable Integer id, @RequestBody FootballPlayer entity) {
return service.save(entity);
}
@ApiOperation(value = "Delete a football player")
@RequestMapping(value = "/delete/{id}", method = RequestMethod.DELETE, produces = "application/json")
public void delete(@PathVariable Integer id) {
service.deleteById(id);
}
@ApiOperation(value = "Search a football player with an ID", response = FootballPlayer.class)
@RequestMapping(value = "/show/{id}", method = RequestMethod.GET, produces = "application/json")
public Optional<FootballPlayer> findById(@PathVariable Integer id) {
return service.findById(id);
}
这样用户就能清楚了解微服务应用暴露的 API 及其目标。
1.4 测试 API
以“Search a football player with an ID” API(路径为
/footballplayer/show/{id}
)为例,Swagger 会显示以下信息:
- HTTP 动词:GET
- API 简要描述
- 调用 API 所需的参数(此处为 Id)
- 不同类型的响应:JSON 对象表示和 HTTP 错误代码
测试 API 的步骤如下:
1. 点击“Try it out”按钮。
2. 插入 ID 参数并点击“Execute”按钮。
3. 查看 API 调用的响应。
2. 使用 Vert.x 构建微服务
Vert.x 是一个用于构建分布式和响应式系统的开源 Eclipse 工具包,基于响应式流原则,提供了编写轻量级和响应式应用程序的灵活方式。它采用异步和非阻塞的开发模型,基于事件循环处理请求,避免客户端长时间等待。
2.1 Maven 设置
Vert.x 与 Apache Maven 3.2 或更高版本兼容,为方便管理所有 Vert.x 依赖,可让 Maven POM 文件继承
vertx-stack-depchain
BOM。以下是一个示例
pom.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
...
<properties>
<java.version>1.8</java.version>
<maven-compiler-plugin.version>3.5.1</maven-compiler-plugin.version>
<maven-shade-plugin.version>2.4.3</maven-shade-plugin.version>
<maven-surefire-plugin.version>2.21.0</maven-surefire-plugin.version>
<exec-maven-plugin.version>1.5.0</exec-maven-plugin.version>
<vertx.version>3.5.4</vertx.version>
...
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-stack-depchain</artifactId>
<version>${vertx.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
...
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>${maven-shade-plugin.version}</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<manifestEntries>
<Main-Class>io.vertx.core.Launcher</Main-Class>
<Main-Verticle>${main.verticle}</Main-Verticle>
</manifestEntries>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>
META-INF/services/io.vertx.core.spi.VerticleFactory
</resource>
</transformer>
</transformers>
<outputFile>
${project.build.directory}/${project.artifactId}-${project.version}-fat.jar
</outputFile>
</configuration>
</execution>
</executions>
</plugin>
...
</plugins>
</build>
</project>
使用以下命令构建和打包应用程序:
$ mvn clean package
2.2 Gradle 设置
Gradle 是一个开源的构建自动化工具,可使用 Groovy 或 Kotlin DSL 编写脚本。要在 Gradle 项目中使用 Vert.x,可创建如下 Gradle 文件:
plugins {
id 'java'
id 'application'
id 'com.github.johnrengelman.shadow' version '2.0.4'
}
ext {
vertxVersion = '3.5.4'
junitJupiterEngineVersion = '5.2.0'
}
repositories {
mavenLocal()
jcenter()
}
group = 'com.packtpub.vertx'
version = '1.0.0-SNAPSHOT'
sourceCompatibility = '1.8'
mainClassName = 'io.vertx.core.Launcher'
def mainVerticleName = 'com.packtpub.vertx.football-player-microservice.MainVerticle'
def watchForChange = 'src/**/*'
def doOnChange = './gradlew classes'
dependencies {
implementation "io.vertx:vertx-core:$vertxVersion"
implementation "io.vertx:vertx-config:$vertxVersion"
...
}
shadowJar {
classifier = 'fat'
manifest {
attributes 'Main-Verticle': mainVerticleName
}
mergeServiceFiles {
include 'META-INF/services/io.vertx.core.spi.VerticleFactory'
}
}
...
run {
args = ['run', mainVerticleName, "--redeploy=$watchForChange", "--launcher-class=$mainClassName", "--on-redeploy=$doOnChange"]
}
构建可执行 JAR 的命令:
$ ./gradlew shadowJar
运行可执行 JAR 的命令:
$ java -jar build/libs/gradle-my-vertx-project.jar
或者使用以下 Gradle 命令运行:
$ ./gradlew run
2.3 构建足球运动员微服务
要构建一个简单的足球运动员微服务,该服务处理足球运动员领域,暴露 CRUD API,并使用 PostgreSQL 数据库存储和检索信息。所需工具及安装信息如下:
| 工具 | 安装链接 |
| ---- | ---- |
| Apache Maven 3.5.4 | https://maven.apache.org/install.html |
| JDK 1.8.0_171 | 推荐 OpenJDK:http://openjdk.java.net/install/ |
| Vert.x 版本 3.5.4 | 后续描述使用说明 |
| Docker Community Edition 18.06.1 | https://docs.docker.com/install/ |
2.4 数据库安装和配置
安装 Docker 后,在新终端窗口中运行以下命令启动 PostgreSQL 容器:
$ docker run --name postgres_vertx -e POSTGRES_PASSWORD=postgresPwd -e POSTGRES_DB=football_players_registry -d -p 5532:5432 postgres
该命令会从 Docker 公共注册表中拉取最新的 PostgreSQL 版本,并下载运行容器所需的所有层。
验证容器是否启动:
$ docker ps -a
查看容器日志:
$ docker logs -f <容器 ID>
连接到容器:
$ docker exec -it <容器 ID> bash
登录 PostgreSQL:
$ psql -U postgres
查看数据库列表:
$ \l
连接到
football_players_registry
数据库:
$ \connect football_players_registry
创建
FOOTBALL_PLAYER
表:
CREATE TABLE FOOTBALL_PLAYER(
ID SERIAL PRIMARY KEY NOT NULL,
NAME VARCHAR(50) NOT NULL,
SURNAME VARCHAR(50) NOT NULL,
AGE INT NOT NULL,
TEAM VARCHAR(50) NOT NULL,
POSITION VARCHAR(50) NOT NULL,
PRICE NUMERIC
);
查看表结构:
$ \d+ football_player
通过以上步骤,我们完成了使用 Spring Boot 和 Vert.x 构建微服务及相关 API 文档配置和数据库设置的过程。这些技术为开发高效、灵活的微服务应用提供了强大的支持。
3. 微服务构建流程总结与对比
3.1 Spring Boot 与 Swagger 集成流程总结
以下是使用 Spring Boot 和 Swagger 集成实现 API 文档化的详细步骤:
1.
添加依赖
:在 Maven 的
pom.xml
文件中添加
springfox-swagger2
和
springfox-swagger-ui
依赖。
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
-
配置 Swagger
:创建
SwaggerConfig类,使用@EnableSwagger2注解启用 Swagger 支持,并配置Docketbean。
@Configuration
@EnableSwagger2
public class SwaggerConfig extends WebMvcConfigurationSupport {
@Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2).select()
.apis(RequestHandlerSelectors.basePackage(
"com.packtpub.springboot.footballplayermicroservice.controller"))
.paths(PathSelectors.any())
.build();
}
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("swagger-ui.html")
.addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/");
}
}
-
自定义 API 信息
:在
SwaggerConfig类中添加metaData方法,设置 API 的元数据信息。
private ApiInfo metaData() {
return new ApiInfoBuilder()
.title("Spring Boot REST API")
.description("\"Spring Boot REST API for Football Player Microservice\"")
.version("1.0.0")
.license("Apache License Version 2.0")
.licenseUrl("https://www.apache.org/licenses/LICENSE-2.0\"")
.contact(new Contact("Mauro Vocale",
"https://github.com/Hands-on-MSA-JakartaEE",
"mauro.vocale@gmail.com"))
.build();
}
-
自定义控制器类
:使用
@ApiOperation和@ApiResponses注解描述控制器方法的操作和响应。
@ApiOperation(value = "View all available football players", response = Iterable.class)
@ApiResponses(value = {
@ApiResponse(code = 200, message = "Successfully retrieved list"),
@ApiResponse(code = 404, message = "The resource you were trying to reach is not found")
})
@RequestMapping(method = RequestMethod.GET, produces = "application/json")
public Iterable<FootballPlayer> findAll() {
return service.findAll();
}
-
运行和测试
:使用
mvn spring-boot:run命令启动应用程序,访问http://localhost:8080/v2/api-docs获取 JSON 格式的 API 文档,访问http://localhost:8080/swagger-ui.html获取可视化的 API 文档。
3.2 Vert.x 微服务构建流程总结
使用 Vert.x 构建微服务的步骤如下:
1.
Maven 设置
:让 Maven POM 文件继承
vertx-stack-depchain
BOM,管理 Vert.x 依赖。
<dependencyManagement>
<dependencies>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-stack-depchain</artifactId>
<version>${vertx.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
- Gradle 设置 :在 Gradle 项目中添加 Vert.x 依赖和相关配置。
plugins {
id 'java'
id 'application'
id 'com.github.johnrengelman.shadow' version '2.0.4'
}
ext {
vertxVersion = '3.5.4'
junitJupiterEngineVersion = '5.2.0'
}
repositories {
mavenLocal()
jcenter()
}
group = 'com.packtpub.vertx'
version = '1.0.0-SNAPSHOT'
sourceCompatibility = '1.8'
mainClassName = 'io.vertx.core.Launcher'
def mainVerticleName = 'com.packtpub.vertx.football-player-microservice.MainVerticle'
def watchForChange = 'src/**/*'
def doOnChange = './gradlew classes'
dependencies {
implementation "io.vertx:vertx-core:$vertxVersion"
implementation "io.vertx:vertx-config:$vertxVersion"
...
}
shadowJar {
classifier = 'fat'
manifest {
attributes 'Main-Verticle': mainVerticleName
}
mergeServiceFiles {
include 'META-INF/services/io.vertx.core.spi.VerticleFactory'
}
}
run {
args = ['run', mainVerticleName, "--redeploy=$watchForChange", "--launcher-class=$mainClassName", "--on-redeploy=$doOnChange"]
}
- 数据库安装和配置 :使用 Docker 启动 PostgreSQL 容器,创建数据库和表。
$ docker run --name postgres_vertx -e POSTGRES_PASSWORD=postgresPwd -e POSTGRES_DB=football_players_registry -d -p 5532:5432 postgres
$ docker ps -a
$ docker logs -f <容器 ID>
$ docker exec -it <容器 ID> bash
$ psql -U postgres
$ \l
$ \connect football_players_registry
$ CREATE TABLE FOOTBALL_PLAYER(
ID SERIAL PRIMARY KEY NOT NULL,
NAME VARCHAR(50) NOT NULL,
SURNAME VARCHAR(50) NOT NULL,
AGE INT NOT NULL,
TEAM VARCHAR(50) NOT NULL,
POSITION VARCHAR(50) NOT NULL,
PRICE NUMERIC
);
$ \d+ football_player
3.3 Spring Boot 与 Vert.x 的对比
| 特性 | Spring Boot | Vert.x |
|---|---|---|
| 开发模型 | 基于 Spring 框架,提供了丰富的注解和组件,开发相对简单,适合快速开发。 | 异步和非阻塞的开发模型,基于事件循环,更适合高并发场景。 |
| 文档生成 | 需要借助 SpringFox 等第三方框架生成 API 文档。 | 未提及内置的 API 文档生成机制,可根据需求集成第三方工具。 |
| 数据库集成 | 支持多种数据库,通过 Spring Data 等模块简化数据库操作。 | 可与多种数据库集成,需要手动编写数据库操作代码。 |
| 生态系统 | 拥有庞大的生态系统,有大量的第三方库和工具可供使用。 | 生态系统相对较小,但提供了灵活的开发方式。 |
4. 总结与展望
通过本文的介绍,我们了解了如何使用 Spring Boot 和 Swagger 集成实现 API 文档化,以及如何使用 Vert.x 构建微服务。Spring Boot 适合快速开发和构建简单的微服务,而 Vert.x 则更适合处理高并发和异步场景。
在实际开发中,可以根据项目的需求和场景选择合适的技术栈。如果项目对开发效率和生态系统有较高的要求,可以选择 Spring Boot;如果项目需要处理大量的并发请求和异步操作,可以选择 Vert.x。
未来,随着微服务架构的不断发展,我们可以期待更多的工具和框架的出现,为微服务的开发和管理提供更好的支持。同时,我们也需要不断学习和掌握新的技术,以适应不断变化的开发需求。
流程图:Spring Boot 与 Swagger 集成流程
graph LR
A[添加依赖] --> B[配置 Swagger]
B --> C[自定义 API 信息]
C --> D[自定义控制器类]
D --> E[运行和测试]
流程图:Vert.x 微服务构建流程
graph LR
A[Maven 设置] --> B[Gradle 设置]
B --> C[数据库安装和配置]
超级会员免费看
684

被折叠的 条评论
为什么被折叠?



