【问题标题】:How REST endpoints are auto subscribed while calling from Browser/REST Client?从浏览器/REST 客户端调用时如何自动订阅 REST 端点?
【发布时间】:2018-11-20 13:07:50
【问题描述】:

在 ProjectReactor 或 Reactive Streams 中,在您订阅()之前什么都不会发生。

除非有人订阅,否则反应式流数据流不会发生,但我看到所有 REST API(如查找、保存和插入)都没有显式调用订阅,但数据在生产者和订阅者之间流动。

@RestController
class PersonController {

      private final PersonRepository repository;

      public PersonController(PersonRepository repository) {
        this.repository = repository;
      }
      @GetMapping("/all")
      public Flux<Person> index() {

         return repository.findAll();

     }
      @GetMapping("/people")
      Flux<String> namesByLastname(@RequestParam Mono<String> lastname) {

        Flux<Person> result = repository.findByLastname(lastname);
        return result.map(it -> it.getFullName());
      }

      @PostMapping("/people")
      Flux<People> AddPeople(@RequestBody Flux<Person> people) {

          return repository.saveAll(people);
      }
}

为什么我们不需要为 REST Endpoints 调用 subscribe 来启动 Project Reactor 中的数据流?

当我从浏览器调用时,REST 端点(HTTP 请求)如何自动订阅 Reactive Streams 以获取数据流?

我错过了什么吗?

【问题讨论】:

  • 反应流就是这样工作的。您需要订阅。这有点像说为什么我需要连接到我的数据库才能运行查询。
  • @Enigmativity 他的问题有点不同。他要问的是(至少我相信如此)当我通过 Java 代码使用 Webclient 调用休息端点时,我需要使用 subscribe(),但是当我从浏览器调用这些休息端点时,它是如何自动订阅的。这是一个公平的问题。
  • @pvpkiran,你是对的。让我换个问题。
  • @PrabuSubra spring web-flux 在 http 服务器上工作,如果您使用 spring-boot,默认情况下它将是 http 服务器“Netty”。 Http 服务器处理传入的 http 请求并订阅具体的发布者。

标签: reactive-programming spring-webflux project-reactor reactive-streams


【解决方案1】:

您是对的 - 当您的应用程序正在设置 Flux/Mono 反应式管道时,该管道中的任何内容都不会执行,直到对其进行 subscribe 处理。

这是 Spring WebFlux 中请求/响应交换期间发生的情况:

  • 服务器收到请求并将其转发给 WebFlux
  • 根据请求和您的应用程序代码,将构建一个反应式管道,包括过滤器、控制器等。您可以将其视为将请求连接到响应的管道
  • HTTP 客户端通过 TCP 堆栈请求读取,并且该背压信息由底层服务器传输。

Spring WebFlux 中最低的合约是HttpHandler - 它是与底层服务器交互的合约。 在 Reactor Netty 的情况下,该服务器已经支持反应流 API,并且订阅是由服务器本地完成的。 对于其他基于 Servlet 的服务器,我们使用反应式流桥接至 Servlet 3.1。在ServletHttpHandlerAdapter 中,我们在反应式流世界和异步 I/O Servlet API 之间架起了一座桥梁——订阅实际上发生在该桥梁内。

另外:请注意,我们通常不会将subscribe 设为WebClient 返回的值;如果您不在反应式管道的中间(即不在控制器处理程序的中间),您只能这样做。在这些情况下,我们通常将其插入管道中间的反应式运算符;如果您不这样做,您将无法保证何时会收到 HTTP 客户端响应 - 这会将该调用与应用程序的其余部分完全分离。

【讨论】:

    猜你喜欢
    • 2013-03-19
    • 2014-03-14
    • 1970-01-01
    • 2022-01-13
    • 2020-04-26
    • 2015-11-29
    • 1970-01-01
    • 2017-06-27
    • 1970-01-01
    相关资源
    最近更新 更多