reactive-programming - 反应式编程如何做决策
问题描述
我是反应式编程的新手。为了动手,我正在尝试构建一个简单的 rest api,但带有请求验证和数据库操作。
这是我想做的步骤。
- 验证传入的请求参数
- 验证后保持继续链并从数据库中获取
- 如果用户在 db 中不存在,则返回一些错误响应
- 如果用户存在,则返回带有用户名的成功响应
注意:由类(UserRequest 和 UserResponse)表示的请求和响应。DB = Mongo 使用响应式驱动程序。
我已经完成了验证工作,但现在我很困惑如何继续以及反应式编程的正确方法是什么。
@Component
public class UserController {
@Autowired
private UserRepository userRepository; // repo has find by id method which returns Mono<User>
public Mono<ServerResponse> handleUserRequest(ServerRequest serverRequest) {
Mono<UserRequest> request = validateRequest(serverRequest);
// what should i do here like now i would like to fetch user from db
return ServerResponse.ok().body("Welcome", String.class);
// how would i return "Welcome <username>";
}
private Mono<UserRequest> validateRequest(ServerRequest request) {
Mono<UserRequest> userRequest = Mono.just(new UserRequest());
Mono<UserRequest> validateUser = userRequest
.map(req -> { //validate id
Optional<String> userid = request.queryParam("userid");
if (user.isPresent() && ObjectId.isValid(userid.get())) {
return req.setUserid(userid.get());
}
throw new RequestEntityValidationException("Invalid user");
});
return validateUser;
}
}
还有任何并排的教程,例如以命令式然后以反应式显示一般代码片段。
解决方案
反应式编程的主要思想是始终使用流链。根据 db data fetching,您可以获取与userRepository.findUserById(id)
此或类似的数据。结果,您将收到Mono<User>
可能有价值或没有价值的信息 - 然后它是一个空的 Mono。
为了处理这种情况,我建议以这种方式编写代码:
public Mono<ServerResponse> handleUserRequest(ServerRequest serverRequest) {
return validateRequest(serverRequest)
.flatMap(userRequest -> userRepository.findUserById(userRequest.getUserId())
.switchIfEmpty(Mono.error(new RuntimeException("Not found")))
)
.flatMap(user -> ServerResponse.ok().body("Welcome " + user.getUsername(), String.class));
}
您可以调整您的validateRequest
方法以使其更具功能性(无需isPresent
检查):
private Mono<UserRequest> validateRequest(ServerRequest request) {
return Mono.just(request)
.map(req -> request.queryParam("userId")
.map(UserRequest::new)
.orElseThrow(() -> new RuntimeException("Invalid user"))
);
}
推荐阅读
- json - 如何 stringfy 值列表
- oracle - Oracle - 创建首选项的 ddl
- symfony - 教义 findBy type="json"
- docker - 什么是 DOCKER_CONTENT_TRUST 标志?
- azure - 为什么不将开发和生产部署混合到 Azure 上的单个 Web 应用程序中?
- json - 多个不同路径的 JSONPath 联合
- spring-boot - 启动 Spring Boot Kafka 项目时出错
- java - Junit 测试未通过。单元测试服务新手
- angular - 角材料步进器在选择更改之前并防止在某些条件下进行步进更改
- python - 如何告诉函数使用默认参数值?