Issue
It seems like a simple question, but I can't find the answer.
In spring-boot, I have a Controller method which returns json:
@GetMapping
public ResponseEntity<Stream<MyObject>> get() {
return ResponseEntity
.ok()
.contentType(MEDIA_JSON)
.body(service.stream());
}
Is this properly streamed to the user (in chunks) or is the whole stream loaded into the memory before returning to the user?
Solution
I did not find anything in the documentation, but it is possible to try and see how it behaves.
Let's create 2 endpoints and an infinite stream of objects:
@RestController
public class MyController {
@GetMapping("/stream")
public ResponseEntity<Stream<MyObject>> stream() {
return ResponseEntity.ok(getStream());
}
@GetMapping("/nostream")
public ResponseEntity<List<MyObject>> noStream() {
return ResponseEntity.ok(getStream().collect(Collectors.toList()));
}
private Stream<MyObject> getStream() {
return IntStream.iterate(0, i -> i + 1)
.mapToObj(i -> new MyObject());
}
static class MyObject {
private String name = "foo";
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
}
Calling http://localhost:8080/stream will respond immediately generating an infinite sequence of [{"name":"foo"},{"name":"foo"}...
If you profile the application you can see that it can proceed for minutes without increasing the memory usage:
Instead, calling the http://localhost:8080/nostream endpoint will result quickly in a java.lang.OutOfMemoryError
:
Answered By - xonya