什么响应类型更适合从响应式端点返回,如果我们返回多个对象?

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

What response type is better to return from reactive endpoint if we return multiple objects?

问题

如果我们在Spring中使用响应式方法,可以在方法中返回Flux/Mono类型。因此,在控制器中,最好将响应包装成ResponseEntity并返回,在返回一个对象的端点中,我们可以编写响应式的代码如下:

@GetMapping(value = "/to-do/{toDoId}", produces = {
            MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE, MediaType.TEXT_XML_VALUE})
public Mono<ResponseEntity<ToDo>> getToDo(@Valid @PathVariable Long toDoId) {
    return repository.findById(toDoId)
            .map(ResponseEntity::ok);
}

但如果我们想返回Flux怎么办?经过一些实验,我找到了以下解决方案:

@GetMapping(value = "/to-do", produces = {
            MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE, MediaType.TEXT_XML_VALUE})
public ResponseEntity<Flux<ToDo>> getToDos() {
    return ResponseEntity.ok().body(
            repository.findAll()
    );
}

但如果我理解正确的话,在这种格式中,ResponseEntity<Flux<ToDo>> 这样的响应将会阻塞吗?所以最好做类似 Flux<ResponseEntity<ToDo>> 的事情?如果是这样,如何实现呢?我需要订阅吗?

英文:

If we use reactive approach in Spring we can return Flux/Mono type in methods. So in controller it's good to wrap response ResponseEntity and return it and in case of endpoints which return one object we can write in reactive next code:

@GetMapping(value = &quot;/to-do/{toDoId}&quot;, produces = {
            MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE, MediaType.TEXT_XML_VALUE})
    public Mono&lt;ResponseEntity&lt;ToDo&gt;&gt; getToDo(@Valid @PathVariable Long toDoId) {
        return repository.findById(toDoId)
                .map(ResponseEntity::ok);
    }

But what if we want to return Flux? After some experiments I found this solution:

@GetMapping(value = &quot;/to-do&quot;, produces = {
            MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE, MediaType.TEXT_XML_VALUE})
    public ResponseEntity&lt;Flux&lt;ToDo&gt;&gt; getToDos() {
        return ResponseEntity.ok().body(
                repository.findAll()
        );
    }

But if I understand correct here in such format, response like ResponseEntity&lt;Flux&lt;ToDo&gt;&gt; will be blocking? So it's better to do something like &lt;Flux&lt;ResponseEntity&lt;ToDo&gt;&gt; ? If it's so, how to get it? I should subscribe?

答案1

得分: 2

只要返回 Mono 或 Flux 即可,似乎不需要真正使用 ResponseEntity 来自定义响应状态。

根据文档,返回 ResponseEntity<Mono> 和 ResponseEntity<Flux> 都可以提供异步、非阻塞的响应:

ResponseEntity<Mono> 或 ResponseEntity<Flux> 可以立即知道响应状态和头部,而请求体会在稍后异步提供。如果响应体包含0..1个值,请使用 Mono,如果可能会产生多个值,请使用 Flux。

英文:

It seems you don't really use the ResponseEntity to customize the reponse status so, why not just return Mono or Flux?

@GetMapping(value = &quot;/to-do/{toDoId}&quot;, produces = {
            MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE, MediaType.TEXT_XML_VALUE})
    public Mono&lt;ToDo&gt; getToDo(@Valid @PathVariable Long toDoId) {
        return repository.findById(toDoId);
    }

@GetMapping(value = &quot;/to-do&quot;, produces = {
            MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE, MediaType.TEXT_XML_VALUE})
    public Flux&lt;ToDo&gt; getToDos() {
        return repository.findAll();
    }

In any case, according to the documentation it's perfectly fine to return ResponseEntity<Mono<T>> and ResponseEntity<Flux<T>>, both will provide an asynchronous, non-blocking response:

> ResponseEntity<Mono<T>> or ResponseEntity<Flux<T>> make the response
> status and headers known immediately while the body is provided
> asynchronously at a later point. Use Mono if the body consists of 0..1
> values or Flux if it can produce multiple values.

答案2

得分: 1

有多种方法可以从响应式控制器中使用ResponseEntity返回值:

Publisher可以是Mono或Flux

  • ResponseEntity&lt;Publisher&lt;T&gt;&gt; - 这会立即确定响应的状态和头信息,但是响应体会在以后的某个时间点异步提供。
  • Publisher&lt;ResponseEntity&lt;T&gt;&gt; - 这提供了全部三者:响应状态、头信息和响应体,都会在以后的某个时间点异步提供。它允许根据异步处理的结果来变化头信息和响应状态。

此外,还可以使用以下结构,虽然不太常见:

  • Mono&lt;ResponseEntity&lt;Publisher&lt;T&gt;&gt;&gt; - 首先异步提供响应状态和头信息,然后异步提供响应体。
英文:

There are multiple ways you can return value using ResponseEntity from your reactive controller:

Publisher can be Mono or Flux

  • ResponseEntity&lt;Publisher&lt;T&gt;&gt; - this makes the response status and headers known immediately while the body is provided asynchronously at some later point of time.
  • Publisher&lt;ResponseEntity&lt;T&gt;&gt; - this provides all three: response
    status, headers, and body, asynchronously at some later point of time. It allows
    the headers and response status to vary depending on the outcome of
    asynchronous handling.

Also it is possible to use the following construct, less common, though:

  • Mono&lt;ResponseEntity&lt;Publisher&lt;T&gt;&gt;&gt; - provide the response status and headers asynchronously first, and later response body, also asynchronously

huangapple
  • 本文由 发表于 2023年2月8日 18:33:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/75384483.html
匿名

发表评论

匿名网友

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

确定