简体   繁体   中英

Spring webflux non-blocking response

I have a request method that use 'username' and 'password' body parameters to find real user from database, validate it by using request password and if everything is fine - return generated token as String.

public Mono<ServerResponse> handleLogin(ServerRequest request) {
    User body = request.bodyToMono(User.class).block();
    return userRepository.findById(body.getUsername())
            .filter(user -> passwordEncoder.matches(body.getPassword(), user.getPassword()))
            .flatMap(user -> ServerResponse.ok().body(Mono.just(tokens.store(user)), String.class))
            .switchIfEmpty(ServerResponse.badRequest().build());
}

This method works fine, but i'm trying to make it as non-blocking and i'm not sure how to achieve it. Any help appreciated.

Updated

For now i changed my method content to

    return request.bodyToMono(User.class)
            .flatMap(body -> userRepository.findById(body.getUsername()).flatMap(user -> Mono.just(new Object[]{body.getPassword(), user})))
            .filter(obj -> {
                User user = (User) obj[1];
                return user.isActive() && passwordEncoder.matches((CharSequence) obj[0], user.getPassword());
            })
            .flatMap(obj -> {
                User user = (User) obj[1];
                return ServerResponse.ok().body(Mono.just(tokens.store(user)), String.class);
            })
            .switchIfEmpty(ServerResponse.badRequest().build());

This is non-blocking, but looks like not so elegant solution. Can it be improved/simplified somehow?

Remember

1) Everything is stream.

2) Keep your flow composed

3) No blocking operation at all.

Solution

So, keep your flow composed without blocking operation

public Mono<ServerResponse> handleLogin(ServerRequest request) {

    return request.bodyToMono(User.class)
                  .flatMap(body -> userRepository.findById(body.getUsername())
                  .filter(user -> passwordEncoder.matches(body.getPassword(), user.getPassword()))
                  .flatMap(user -> ServerResponse.ok().body(Mono.just(tokens.store(user)), String.class))
                  .switchIfEmpty(ServerResponse.badRequest().build());
}

Regarding the last update

Regarding the last update, from my point of view, the code might be optimized in a next way:

return request.bodyToMono(User.class)
            .flatMap(body -> userRepository.findById(body.getUsername())                              
                                           .filter(user -> user.isActive())
                                           .filter(user -> passwordEncoder.matches(body.getPassword(), user.getPassword()))
            )
            .flatMap(user -> ServerResponse.ok().syncBody(tokens.store(user)))
            .switchIfEmpty(ServerResponse.badRequest().build());

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM