Spring Webflux如何在不阻塞的情况下依次调用2个不同的服务?

huangapple go评论73阅读模式
英文:

Spring Webflux How to do call 2 different services sequentially without blocking?

问题

我遇到了与WebFlux有关的问题。

让我描述一下我想要同步执行的内容。

首先,我想要将产品保存到数据库并获得生成的ID。

接下来,我想要保存产品的评论,带有产品ID。

我希望能在一个微服务控制器的单个服务调用中完成这些操作。我不清楚在没有阻塞的情况下如何在控制器中实现这一点(我知道这是不应该做的事情)。

我将数据发送到我的RestController,如下所示:

{
  "name": "product 1",
  "weight": 5,
  "reviews": [
    {
      "rating": 5,
      "post": "review post"
    },
    {
      "rating": 10,
      "post": "Second review post"
    }
  ]
}
public class MyService {
  // 这将调用另一个微服务并返回带有保存的产品的Mono
  public Mono<Product> saveProduct(Product product) { ... }

  // 这将调用另一个微服务来保存评论
  public Mono<Void> saveReview(Review review) { ... }
}
@RestController
public class MyController {

  @Autowired
  MyService service;
  
  @PostMapping("/composite-product")
  public Mono<Void> saveCompositeProduct(CompositeProduct cp) {
    // 此时id为空
    Product product = new Product(cp.getName(), cp.getWeight());
   
    return service.saveProduct(product)
      .flatMapMany(savedProduct -> {
         if(cp.getReviews() == null) return Flux.empty();
         
         // 我向评论添加产品id
         List<Review> reviews = cp.getReviews().stream()
           .map(review -> new Review(savedProduct.getId(), review.getRating(), review.getPost()))
           .collect(Collectors.toList());

        // 我尝试保存评论,但不起作用,因为没有任何东西订阅它。
        // 我不想添加任何类型的subscribe方法或block方法,我知道在WebFlux应用程序中这样做是错误的
         return Flux.fromIterable(reviews)
           .flatMap(r -> service.saveReview(r));
      }).then();
  }
}

我该如何让这个工作起来?

英文:

I am having an issue with webflux

let me describe what I want to do synchronously.

First, I want to save a product to the db and get a generated ID

Next I want to save reviews of the product with productId.

I want to do this in one service call to the microservice controller. I do not see how this can be accomplished in controller without blocking (which I know is something I should not do)

I am sending data like the following to my restcontroller

{
  name: &quot;product 1&quot;,
  weight: 5,
  reviews: [
  {
      rating: 5,
      post: &quot;review post&quot;
  }, {
     rating: 10,
     post: &quot;Second review post&quot;
  }]
}

public class MyService {
  //This will call another micro-service and returns a Mono with the saved product
  public Mono&lt;Product&gt; saveProduct(Product product) { ... }

  //This will call another micro-service to save the review
  public Mono&lt;Void&gt; saveReview(Review review) { ... }
}

@RestController
public class MyController {

@Autowired
MyService service;

@PostMapping(&quot;/composite-product&quot;)
public Mono&lt;Void&gt; saveCompositeProduct(CompositeProduct cp) {
  // The id is null at this time
  Product product = new Product(cp.getName(), cp.getWeight());
 
  return service.saveProduct(product)
    .flatMapMany(savedProduct -&gt; {
       if(cp.getReviews() == null) return Flux.empty();
       
       // I add the product id to the review
       List&lt;Review&gt; reviews = cp.getReviews().stream()
         .map(review -&gt; new Review(savedProduct.getId(), review.getRating(), review.getPost())
         .collect(Collectors.toList());

      // I try to save the reviews but it does not work because nothing ever 
      //subscribes to it. I do not want to add any type of subscribe method
      // or block method which I know is wrong to have in a webflux application
       return Flux.fromIterable(reviews)
         .map(r -&gt; service.saveReview(r));
    }).then();
}

How can I make this work?

答案1

得分: 0

使用flatMap而不是map操作符。flatMap内部像flatMapMany一样订阅了Mono,就像Flux订阅一样。

return Flux.fromIterable(reviews)
           .flatMap(r -> service.saveReview(r));
英文:

Use flatMap instead of map operator. flatMap subscribes to Mono internally just like flatMapMany does to Flux.

return Flux.fromIterable(reviews)
           .flatMap(r -&gt; service.saveReview(r));

huangapple
  • 本文由 发表于 2020年9月6日 10:39:04
  • 转载请务必保留本文链接:https://go.coder-hub.com/63760224.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定