使用 Rest API、Spring Boot、Maven 和 Fauna 构建任务管理应用程序
与“与动物一起写作”计划相关而撰写。
本文重点介绍使用 Java 编程框架 (Spring Boot)、Maven 和 Fauna 构建 Rest API 的教程步骤。我们使用 Fauna 作为数据库来保存信息,并将其集成到 Spring Boot 项目中。我们还概述了这些步骤,以便初学者在处理类似项目时轻松遵循并使用这些步骤实现相同的功能。Rest
API 更适合服务器端 API 渲染。因此,REST API 因其简单性、可扩展性和灵活性而成为微服务的一种宝贵架构风格。在微服务架构中,每个应用程序都被设计为相互独立的服务。我们记得,微服务依赖于小型团队来独立部署和扩展各自的服务,这使得 REST API 成为这种架构风格的宝贵资源。
先决条件
为了完全理解本教程的这一部分,您需要具备以下内容:
- 有关如何使用 Java 编程的基础知识。
- 至少具备 Spring Framework 和 Spring Boot 的基础知识。
- 已安装Java 开发工具包 (JDK)。
- Postman安装好或者点击链接下载安装。
- Maven安装或者点击链接下载安装。
- 已安装IntelliJ或点击链接进行安装。您也可以使用任何其他 IDEA。
什么是 API?
简单来说,API 是应用程序编程接口的缩写,它允许两个或多个不同的应用程序相互通信。每次使用这些应用程序时,手机、小工具或计算机上的应用程序都会连接到互联网并向服务器发送数据。然后,服务器会解释这些数据,执行一些操作,并以人类可读的格式将反馈返回给您。API 还提供了一定程度的安全性,因为每次通信都只需要一小包数据,因此此处的数据共享仅包含必要的数据。RESTful API 的另一个好处是它的客户端-服务器约束。此约束基于客户端和服务器端应彼此分离的概念。这称为关注点分离,它保证了应用程序的更高效率。因此,我应该能够在客户端进行更改,而不会影响服务器上的数据库设计,反之亦然。这使得我们的应用程序松散耦合且易于扩展。
本文教你如何创建一个 SpringBoot 和 Restful API,通过调用 Fauna 的数据库来执行 CRUD(创建、读取、更新和删除)操作。本教程将构建一个“任务管理应用”,供用户管理所有日常任务。
关键要点
- 如何使用 Tomcat 服务器创建和设置 Spring Boot 应用程序。
- Spring Boot 项目中的 Fauna 数据库配置。
- Maven 用于依赖管理。
- Java 中的异常处理。
- 如何使用 Swagger 记录 API。
项目设置
为了初始化项目,我们将使用spring 初始化程序 。输入项目的 Maven 项目属性(包括如下所示的依赖项),然后单击“生成”按钮。这将生成一个 zip 文件并为您下载。解压后,在您常用的 IDEA 中打开它,并将依赖项与 Maven 同步。
对于这个项目,我们将添加两个依赖项,即:
- Spring web:此依赖项使您的项目成为一个 Web 应用程序。spring-boot-starter-web 依赖项会以传递方式引入与使用 Spring MVC、REST 和 Tomcat 作为默认嵌入式服务器进行 Web 开发相关的所有依赖项。
- Spring Data JPA:这使我们能够使用 Spring Data 和 Hibernate(JPA 的一个实现)将数据持久化到 SQL 数据库中。JPA 代表 Java 持久性 API,它是 Java EE(企业版)的一部分,定义了对象关系映射 (ORM) 以及管理持久对象和关系数据库的 API。它被认为是对象关系映射的标准方法。由于 JPA 是一个规范,它本身并不执行任何操作,因此需要实现。Hibernate 是实现 JPA 的 ORM(对象关系映射)工具之一。其他实现 JPA 的工具包括 TopLink 和 MyBatis。
应用程序的入口点
SpringBoot 的魅力在于它可以轻松创建独立的、基于 Spring 的生产级应用程序,并且“直接运行”。如果你打开 TaskManagerApplication.java 文件。
package com.taskVentures.taskmanager;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Scope;
@SpringBootApplication
public class TaskmanagerApplication {
public static void main(String[] args) {
SpringApplication.run(TaskmanagerApplication.class, args);
}
}
SpringBoot 应用程序应该有一个带有 public static void main(String[] args) 方法的入口点类,该方法用@SpringBootApplication
注释进行注释,并将用于引导应用程序。它是主方法,是 JVM 运行我们应用程序的入口点。
该@SpringBootApplication
注释通知 Spring 框架在启动时扫描此包内的 Spring 组件并注册它们。它还告诉 Spring Boot 启用自动配置,这是一个根据类路径设置、属性设置和其他因素自动创建 Bean 的过程。注释由三个注释(即、和)@SpringBootApplication
组成功能。因此,我们可以说它是这三个注释的快捷方式。@EnableAutoConfiguration
@ComponentScan
@Configuration
现在,我们可以运行我们的应用程序了。我们可以通过点击 IDEA 上的播放按钮,或者在命令行中运行以下命令:mvn spring-boot:run。通过命令行导航到项目根目录并执行该命令。轰隆隆!Tomcat 在端口 8081 上启动了,这正是我们配置应用程序运行的端口。
Maven 作为依赖管理工具。
pom.xml 文件包含我们项目中的依赖项和 Maven 插件。
依赖项部分仅包含我们添加到项目中的依赖项,即 SpringWeb 和 springfox,用于记录我们的 API。
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.taskVentures</groupId>
<artifactId>taskmanager</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>taskmanager</name>
<description>A web application that individual to manage their daily task.</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
添加其他 Maven 依赖项
在本节中,我们将为项目添加其他缺陷。为此,我们导航到Maven 存储库并搜索 Fauna 依赖项,然后将其添加到 pom.xml 文件的依赖项部分:
- Faunadb: Fauna 云数据库依赖项,将我们的 Java 应用程序连接到 Fuana 无服务器数据库。
- Lombok: Lombok 依赖项帮助我们减少样板代码。
- 将新添加的依赖项同步到应用程序。
- 修改后的pom.xml应该是这样的:
<!--newly added dependencies-->
<dependency>
<groupId>com.faunadb</groupId>
<artifactId>faunadb-java</artifactId>
<version>2.10.0</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.20</version>
<scope>provided</scope>
</dependency>
接下来,我们可以在 Fauna 仪表板上创建数据库,生成服务器密钥并在 Spring Boot 项目中配置 FaunaClient。为了为我们的 SpringBoot 项目创建数据库和服务器密钥,我们需要注册一个 Fauna 帐户。点击此链接立即注册,如果您已有帐户,请忽略。注册后,您将收到创建数据库的提示,如下图所示:
这里,我们将数据库命名为 taskmanager_db。命名数据库时,请务必使用描述性的名称。接下来,我们将生成 Fauna 密钥。
创建 Fauna API 密钥
要创建 Fauna API 密钥,您需要前往 Fauna 侧边栏(屏幕左上角)的设置页面。此 Fauna API 密钥用于将数据库连接到我们的 Task_Management_App。
Fauna 生成的密钥应该被复制并存储在安全的地方,以便于检索。
配置 Fauna 客户端
在 src/main 文件夹内的资源文件夹中,打开 application.properties 文件并添加您生成的密钥。fauna
-db.secret=”your api secret key should be here”
接下来,我们需要创建一个 bean,在注释的帮助下创建配置的单个实例@Scope
,并使用注释注入我们的 api 密钥@value
。
@Value("${fauna-db.secret}")
private String serverKey;
@Bean
@Scope(value = ConfigurableBeanFactory.SCOPE_SINGLETON)
public FaunaClient faunaConfiguration() {
FaunaClient faunaClient = FaunaClient.builder()
.withSecret(serverKey)
.build();
return faunaClient;
}
项目结构
我们的项目将分为四个子包:
数据:此子包将容纳我们的数据访问层,其中包括我们的域和存储库。
- 服务:这是我们的业务逻辑所在。
- 网络:这个包将容纳我们的控制器。
- 异常:所有自定义异常都将存放在这里。抛出异常对于构建弹性系统至关重要。这种结构将确保当客户端调用访问应用程序中的资源时,该客户端无法直接访问我们的数据库,而是将请求定向到我们的控制器。我们的控制器会调用正确的服务(业务逻辑),然后该服务会通过我们的存储库调用我们的数据库。这种架构还确保了关注点分离。
创建域类
在 data 包中,创建另一个名为 models 的包。在 models 包内,创建一个名为 Task 的类,代码如下:
package com.taskVentures.taskmanager.data.models;
import com.faunadb.client.types.FaunaConstructor;
import com.faunadb.client.types.FaunaField;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
public class Task {
private String id;
@FaunaField
private String name;
@FaunaField
private String description;
@FaunaField
private boolean isCompleted;
@FaunaConstructor
public Task(@FaunaField("id")String id, @FaunaField("name")String name, @FaunaField("description")String description, @FaunaField("isCompleted")boolean isCompleted) {
this.id = id;
this.name = name;
this.description = description;
this.isCompleted = isCompleted;
}
}
- @FaunaField注释使实例变量被注释为数据库列
- 我们使用@FaunaConstructor 注释来指定我们的创建构造函数并在创建时赋予我们的文件值。
- @data为该类创建 setter 和 getter。
- @NoArgsConstructor注释创建一个无参数的构造函数。
- @AllArgsContructor创建一个全参数构造函数。
有效载荷
在数据包中,创建一个名为“payloads”的包。该包将包含两个子包“request”和“response”,分别用于处理请求负载和响应负载。
请求负载
在请求包内创建一个 EmployeeRequest 类,代码如下:
package com.taskVentures.taskmanager.data.payloads.requests;
import lombok.Data;
import java.time.LocalDateTime;
@Data
public class TaskRequest {
@NotNull
@NotBlank
private String name;
@NotNull
@NotBlank
private String description;
private boolean isCompleted;
}
@notblank和 @NotNull :这两个注释分别检查并验证它们映射的字段,以确保值不为空和不为空。
响应有效载荷
在响应包内创建一个TaskResponse 类,代码如下:
package com.taskVentures.taskmanager.data.payloads.response;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class TaskResponse {
private String message;
}
- 上面的代码只是一个 POJO(普通旧 Java 对象),它有一个实例变量、一个构造函数、一个赋值器(setter)和一个访问器(getter)。
存储库
在数据包中,创建一个名为“repository”的子包。然后创建一个名为“TaskRepository”的接口,该接口扩展了 JpaRepository。JpaRepository 是泛型接口,因此它接受一个模型类(Type)和主键的数据类型。在 TaskRepository 接口中写入以下代码。
package com.taskVentures.taskmanager.data.repository;
import com.taskVentures.taskmanager.data.models.Task;
import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.concurrent.CompletableFuture;
@Repository
public class TaskRepository extends FaunaRepository<Task> {
public TaskRepository(){
super(Task.class, "todos", "tasks");
}
@Override
public CompletableFuture<List<Task>> findAll() {
return null;
}
}
- @Repository将接口转换为 Bean。它与@Component注解的处理方式相同,因此它是@Component注解的特化版本。
Beans
它们只是 Spring 所支持的 Java 类。
接下来,让我们创建一个名为 FaunaRepository 的类,它将包含允许我们执行CRUD操作的方法。我们首先要创建一个包含这些方法的接口。我们称之为接口Repository
。
package com.taskVentures.taskmanager.data.repository;
import com.taskVentures.taskmanager.data.models.Task;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
public interface Repository<T extends Task> {
CompletableFuture<T> save(T entity);
CompletableFuture<Optional<T>> find(String id);
CompletableFuture<Optional<T>> remove(String id);
}
- 我们定义了一个接口,其中包含允许我们保存、查找和更新任务的方法。“Java
包 com.taskVentures.taskmanager.data.repository;
导入 com.faunadb.client.FaunaClient;
导入 com.faunadb.client.errors.NotFoundException;
导入 com.faunadb.client.query.Expr;
导入 com.faunadb.client.query.Language;
导入 com.faunadb.client.types.Value;
导入 com.taskVentures.taskmanager.data.models.Task;
导入 org.springframework.beans.factory.annotation.Autowired;
导入 java.util.Optional;
导入 java.util.concurrent.CompletableFuture;
导入 java.util.function.Function;
导入静态 com.faunadb.client.query.Language.*;
导入 java.lang.Class;
公共抽象类 FaunaRepository 实现 Repository,IdentityFactory {
@Autowired
protected FaunaClient faunaClient;
protected final Class<T> entityType;
protected final String collectionName;
protected final String collectionIndexName;
protected FaunaRepository(Class<T> entityType, String collectionName, String collectionIndexName) {
this.entityType = entityType;
this.collectionName = collectionName;
this.collectionIndexName = collectionIndexName;
}
@Override
public CompletableFuture<String> nextId() {
CompletableFuture<String> result =
faunaClient.query(
NewId()
)
.thenApply(value -> value.to(String.class).get());
return result;
}
@Override
public CompletableFuture<T> save(T entity) {
CompletableFuture<T> result =
faunaClient.query(
saveQuery(Language.Value(entity.getId()), Value(entity))
)
.thenApply(this::toEntity);
return result;
}
@Override
public CompletableFuture<Optional<T>> remove(String id) {
CompletableFuture<T> result =
faunaClient.query(
Select(
Value("data"),
Delete(Ref(Collection(collectionName), Value(id)))
)
)
.thenApply(this::toEntity);
CompletableFuture<Optional<T>> optionalResult = toOptionalResult(result);
return optionalResult;
}
@Override
public CompletableFuture<Optional<T>> find(String id) {
CompletableFuture<T> result =
faunaClient.query(
Select(
Value("data"),
Get(Ref(Collection(collectionName), Value(id)))
)
)
.thenApply(this::toEntity);
CompletableFuture<Optional<T>> optionalResult = toOptionalResult(result);
return optionalResult;
}
protected Expr saveQuery(Expr id, Expr data) {
Expr query =
Select(
Value("data"),
If(
Exists(Ref(Collection(collectionName), id)),
Replace(Ref(Collection(collectionName), id), Obj("data", data)),
Create(Ref(Collection(collectionName), id), Obj("data", data))
)
);
return query;
}
protected T toEntity(Value value) {
return value.to(entityType).get();
}
protected CompletableFuture<Optional<T>> toOptionalResult(CompletableFuture<T> result) {
CompletableFuture<Optional<T>> optionalResult =
result.handle((v, t) -> {
CompletableFuture<Optional<T>> r = new CompletableFuture<>();
if(v != null) r.complete(Optional.of(v));
else if(t != null && t.getCause() instanceof NotFoundException) r.complete(Optional.empty());
else r.completeExceptionally(t);
return r;
}).thenCompose(Function.identity());
return optionalResult;
}
}
The above class provides an implementation to the methods defined on the interface.
You can look up the Fauna documentation for Java by clicking on this link: [Fauna/JVM doc](https://docs.fauna.com/fauna/current/drivers/jvm)
```Java
package com.taskVentures.taskmanager.data.repository;
import java.util.concurrent.CompletableFuture;
public interface IdentityFactory {
CompletableFuture<String> nextId();
}
任务服务
在 taskmanager 目录下创建一个服务包。此包将用于存放业务逻辑。我们将服务分为两个部分:一个接口,用于声明业务逻辑的方法;以及一个具体类,用于实现该接口。使用以下代码创建一个名为“taskService”的接口:
package com.taskVentures.taskmanager.services;
import com.taskVentures.taskmanager.data.models.Task;
import com.taskVentures.taskmanager.data.payloads.requests.TaskRequest;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
@component
public interface TaskService {
CompletableFuture<Task> createTask(TaskRequest taskRequest);
CompletableFuture<Optional<Task>> updateTask(String id, TaskRequest taskRequest);
CompletableFuture<Optional<Task>> deleteTask(String id);
CompletableFuture<Optional<Task>> getTask(String id);
}
- @Component注解是该注解的简写
@Bean
。它将 TaskService 接口注册为应用程序上下文中的 Bean,并使其在类路径扫描期间可访问。我们创建了五个方法,分别用于创建、更新、获取和删除任务。
接下来创建一个实现 TaskService 接口的 TaskServiceImpl 类,编写如下代码:
package com.taskVentures.taskmanager.services;
import com.taskVentures.taskmanager.data.models.Task;
import com.taskVentures.taskmanager.data.payloads.requests.TaskRequest;
import com.taskVentures.taskmanager.data.repository.TaskRepository;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
@Service
@AllArgsConstructor
public class TaskServiceImpl implements TaskService {
private final TaskRepository taskRepository;
@Override
public CompletableFuture<Task> createTask(TaskRequest taskRequest) {
CompletableFuture<Task> newTask = taskRepository.nextId()
.thenApply(id -> new Task(id, taskRequest.getName(), taskRequest.getDescription(), taskRequest.isCompleted())).thenCompose(taskRepository::save);
return newTask;
}
@Override
public CompletableFuture<Optional<Task>> getTask(String id) {
return taskRepository.find(id);
}
@Override
public CompletableFuture<Optional<Task>> updateTask(String id, TaskRequest taskRequest) {
CompletableFuture<Optional<Task>> result =
taskRepository.find(id)
.thenCompose(optionalTodoEntity ->
optionalTodoEntity
.map(todoEntity -> taskRepository.save(new Task(id, taskRequest.getName(), taskRequest.getDescription(), taskRequest.isCompleted())).thenApply(Optional::of))
.orElseGet(() -> CompletableFuture.completedFuture(Optional.empty())));
return result;
}
@Override
public CompletableFuture<Optional<Task>> deleteTask(String id) {
return taskRepository.remove(id);
}
}
@Service注解是 的一种特殊形式@Component
。使用@Service注解,被注解的类将在应用程序上下文中注册,并在类路径扫描期间可访问。
TaskServiceImpl 类通过重写并实现 TaskService 接口的方法来实现它。
当获取单个任务时,如果数据库中不存在传入的 ID,该类会抛出异常(ResourceNotFoundException - 这是我们自定义的继承自 RunTimeException 的异常类)。
控制器
在taskmanager 包下创建一个名为web的包。这个包将用于存放 API 控制器。使用以下代码创建一个 TaskController 类:
package com.taskVentures.taskmanager.web;
import com.taskVentures.taskmanager.data.payloads.requests.TaskRequest;
import com.taskVentures.taskmanager.services.TaskService;
import io.swagger.annotations.ApiResponses;
import lombok.AllArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.concurrent.CompletableFuture;
@RestController
@RequestMapping("/task")
@AllArgsConstructor
@ApiResponses(value = {
@io.swagger.annotations.ApiResponse(code = 400, message = "This is a bad request, please follow the API documentation for the proper request format"),
@io.swagger.annotations.ApiResponse(code = 401, message = "Due to security constraints, your access request cannot be authorized"),
@io.swagger.annotations.ApiResponse(code = 500, message = "The server is down. Please bear with us."),
})
public class TaskController {
TaskService taskService;
@PostMapping("/create")
public CompletableFuture<?> createTask(@RequestBody TaskRequest taskRequest) {
return taskService.createTask(taskRequest)
.thenApply(todoEntity -> new ResponseEntity<>(todoEntity, HttpStatus.CREATED));
}
@GetMapping("/get/{id}")
public CompletableFuture<?> getTask(@PathVariable("id") String id) {
CompletableFuture<ResponseEntity> result =
taskService.getTask(id)
.thenApply(optionalTodoEntity ->
optionalTodoEntity
.map(todoEntity -> new ResponseEntity<>(todoEntity, HttpStatus.OK))
.orElseGet(() -> new ResponseEntity<>(HttpStatus.NOT_FOUND))
);
return result;
}
@PutMapping("/update/{id}")
public CompletableFuture<?> updateTask(@PathVariable("id") String id, @RequestBody TaskRequest taskRequest) {
CompletableFuture<ResponseEntity> result =
taskService.updateTask(id, taskRequest)
.thenApply(optionalTodoEntity ->
optionalTodoEntity
.map(todoEntity -> new ResponseEntity<>(todoEntity, HttpStatus.OK))
.orElseGet(() -> new ResponseEntity<>(HttpStatus.NOT_FOUND)
)
);
return result;
}
@DeleteMapping(value = "/delete/{id}")
public CompletableFuture<?> deleteTask(@PathVariable("id")String id) {
CompletableFuture<ResponseEntity> result =
taskService.deleteTask(id)
.thenApply(optionalTodoEntity ->
optionalTodoEntity
.map(todo -> new ResponseEntity<>(todo, HttpStatus.OK))
.orElseGet(() -> new ResponseEntity<>(HttpStatus.NOT_FOUND)
)
);
return result;
}
}
- @RestController:此注释将 EmployeeController 标记为 HTTP 请求处理程序,并允许 Spring 将其识别为 RESTful 服务。
- @RequestMapping("/task")注解将控制器中资源端点的基本路径设置为 /task。接下来,我们注入了 TaskService 类。
- @GetMapping是 @RequestMapping(method = RequestMethod.GET) 的快捷方式,用于将 HTTP GET 请求映射到映射的控制器方法。我们使用它来返回所有任务和单个任务。
- @PathVariable注释表明方法参数应该绑定到 URI 模板变量。
- @PostMapping是 @RequestMapping 的简写,其中 method 等于 POST。它用于将 HTTP POST 请求映射到映射的控制器方法。
- @RequestBody:此注解负责在已注册的 HttpMessageConverters 的帮助下将 Web 请求主体绑定到方法参数。因此,当您向“/task/add”URL 发出包含 Post JSON 主体的 POST 请求时,HttpMessageConverters 会将 JSON 请求主体转换为 Post 对象,并将其传递给 createTask 方法。
- @PutMapping是 @RequestMapping 的简写,其中 method 等于 PUT。它用于将 HTTP PUT 请求映射到映射的控制器方法。
- @DeleteMapping:使用此注解使 Mapped 控制器方法准备好执行删除操作。是@RequestMapping (method = RequestMethod.DELETE) 的快捷方式。
使用 Swagger 记录你的 API
我们已经将 io.springfox 依赖项添加到 pom.xml 中。通过此依赖项,我们将记录 API,以便其他开发人员轻松使用。只需在控制器的类级别添加以下代码行即可:
@ApiResponses(value = {
@io.swagger.annotations.ApiResponse(code = 400, message = "This is a bad request, please follow the API documentation for the proper request format"),
@io.swagger.annotations.ApiResponse(code = 401, message = "Due to security constraints, your access request cannot be authorized"),
@io.swagger.annotations.ApiResponse(code = 500, message = "The server is down. Please bear with us."),
})
我们在类级别添加了来自 Swagger 的@ApiResponse
注解。就这么简单,我们的 API 已完整记录。 访问localhost:8081/swagger-ui即可访问文档,并测试 API 是否仍然正常运行。使用localhost:8900/swagger-ui
上的 Swagger API 文档可以添加、获取、更新和删除员工。
结论
在本项目中,我们成功构建了一个任务管理应用程序,并使用SpringBoot
框架和Maven
作为我们的依赖项管理和构建工具。我们将其用作Fauna
云数据存储。
此外,我们还学习了如何在应用程序中抛出异常,以确保应用程序具有容错能力和弹性。我们还学习了如何使用来记录我们的 API 。您可以通过以下链接从我的GitHubSwagger
克隆该项目: Task_Management_SpringBoot_Project 。如有任何疑问,请随时通过我的任何社交媒体联系我: