首页 > 解决方案 > 反应式编程如何做决策

问题描述

我是反应式编程的新手。为了动手,我正在尝试构建一个简单的 rest api,但带有请求验证和数据库操作。

这是我想做的步骤。

  1. 验证传入的请求参数
  2. 验证后保持继续链并从数据库中获取
    • 如果用户在 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;
    }
}

还有任何并排的教程,例如以命令式然后以反应式显示一般代码片段。

标签: reactive-programmingproject-reactor

解决方案


反应式编程的主要思想是始终使用流链。根据 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"))
            );
}

推荐阅读