Весенний webflux: webClient положил вызов - PullRequest
0 голосов
/ 15 января 2020

У меня есть учетная запись и продукт службы общения. Когда от пользователя приходит запрос на покупку продукта (я не включил службу пользователя, она работает нормально, а не проблему), служба продукта проверяет, достаточно ли средств на счете и есть ли они. обновляет баланс. Следующий код работает нормально:

@GetMapping("/account/{userId}/product/{productId}")
    public Mono<ResponseEntity<Product>> checkAccount(@PathVariable("userId") int userId,@PathVariable("productId") int productId){



    Mono<Account> account =  webClientBuilder.build().get().uri("http://account-service/user/accounts/{userId}/",userId)
                        .retrieve().bodyToMono(Account.class);


    Mono<Product> product = this.ps.findById(productId);

    Mono<Boolean> result = account.zipWith(product,this::isAccountBalanceGreater);


    Mono<ResponseEntity<Product>> p = result.zipWith(product,this::getResponse);

    return p;

    }



    public boolean isAccountBalanceGreater(Account acc, Product prd) {
           return(acc.getBalance()>=prd.getPrice()):
        }




    public ResponseEntity<Product> getResponse(boolean result,Product prod){
        if(result) {

            return ResponseEntity.accepted().body(prod);
        }else {
            return ResponseEntity.badRequest().body(prod);
        }
    }

Мой метод put в службе учетных записей также работает нормально:

@PutMapping("/account/update/{accountId}")
    public Mono<ResponseEntity<Account>> updateAccount(@PathVariable("accountId") int accountId, @RequestBody Account account) {


      return as.findById(accountId)
              .flatMap(oldAcc->{
                  oldAcc.setAccountId(account.getAccountId());
                  oldAcc.setAccountId(account.getAccountId());
                    oldAcc.setOwner(account.getOwner());
                    oldAcc.setPin(account.getPin());
                    oldAcc.setBalance(account.getBalance());
                    oldAcc.setUserId(account.getUserId());
                    return ar.save(oldAcc);
              }).map(a -> ResponseEntity.ok(a))
                .defaultIfEmpty(ResponseEntity.notFound().build());


    }

Теперь я хочу обновить весы, я пробовал это в методе isAccountBalancerGreater:

public boolean isAccountBalanceGreater(Account acc, Product prd) {
           if(acc.getBalance() >= prd.getPrice()) {

               double newBuyerBalance  =acc.getBalance() - prd.getPrice();

                Account newOwnerAcc = new Account(acc.getAccountId(),acc.getOwner(),acc.getPin(),newBuyerBalance,acc.getUserId());


                this.ps.removeProduct(prd.getProductId());


  webClientBuilder.build().put().uri("http://account-service/account/update/{accountId}",acc.getAccountId()).body(newOwnerAcc,Account.class).exchange();



              return true;
           }
           return false;
        }

Однако это не работает, не ошибка, просто ничего не обновляется. Мой тестовый пример работает, когда я запускаю тот же код с тестовой учетной записью. Я не уверен, почему это не выполняется. Есть предложения?

1 Ответ

1 голос
/ 16 января 2020

вы должны думать о реактивном коде как о цепочке событий или обратных вызовах. Поэтому вам нужно реагировать на то, что вы хотите, чтобы что-то делало, после того, как что-то еще было завершено.

return webClientBuilder.build()
          .put().uri("http://account-service/account/update/{accountId}",
                         acc.getAccountId())
                         .body(newOwnerAcc,Account.class)
                         .exchange()
                         .thenReturn(true); // if you really need to return a boolean

возвращение логического значения обычно не семантически правильно в реактивном мире. Очень часто стараются избегать операторов if-else

. Один из способов - вернуть Mono<Void>, чтобы отметить, что что-то выполнено, и вызвать что-то, связанное с ним.

public Mono<Void> isAccountBalanceGreater(Account acc, Product prd) {
    return webclient.put()
                    .uri( ... )
                    .retrieve()
                    .bodyToMono(Void.class)
                    .doOnError( // handle error )
 }

// How to call for example
isAccountBalanceGreater(foo, bar)
    .doOnSuccess( ... )
    .doOnError( ... ) 
...