Skip to content

Commit e42735e

Browse files
committed
Add JsonStreamResponse documentation
1 parent 5756f27 commit e42735e

2 files changed

Lines changed: 82 additions & 0 deletions

File tree

docs/en/controllers/request-response.md

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -927,6 +927,65 @@ $stream = new CallbackStream(function () use ($img) {
927927
$response = $response->withBody($stream);
928928
```
929929

930+
### Streaming Large JSON Responses
931+
932+
`class` **Cake\\Http\\Response\\JsonStreamResponse**
933+
934+
When you need to send a large JSON response, `JsonStreamResponse` lets you
935+
stream each item instead of building the entire payload in memory first. This
936+
is useful for large exports, APIs backed by database cursors, or any response
937+
where buffering the full result would be wasteful.
938+
939+
```php
940+
use Cake\Http\Response\JsonStreamResponse;
941+
942+
public function index()
943+
{
944+
$articles = $this->fetchTable('Articles')
945+
->find()
946+
->select(['id', 'title', 'created'])
947+
->enableHydration(false)
948+
->bufferResults(false);
949+
950+
return new JsonStreamResponse($articles);
951+
}
952+
```
953+
954+
`JsonStreamResponse` sets the `Content-Type` header to `application/json` by
955+
default and disables proxy buffering with the `X-Accel-Buffering: no` header.
956+
957+
If you need newline-delimited JSON instead of a JSON array, use the
958+
`JsonStreamResponse::FORMAT_NDJSON` format:
959+
960+
```php
961+
use Cake\Http\Response\JsonStreamResponse;
962+
963+
public function stream()
964+
{
965+
$query = $this->fetchTable('Articles')
966+
->find()
967+
->select(['id', 'title'])
968+
->enableHydration(false)
969+
->bufferResults(false);
970+
971+
return new JsonStreamResponse($query, [
972+
'format' => JsonStreamResponse::FORMAT_NDJSON,
973+
]);
974+
}
975+
```
976+
977+
You can customize the output with these options:
978+
979+
- `root`: Wraps the payload in a top-level object.
980+
- `envelope`: Adds additional top-level keys alongside the streamed data.
981+
- `dataKey`: Renames the streamed collection key when using `root`.
982+
- `transform`: Applies a callback to each item before encoding it.
983+
- `flags`: Sets the `json_encode()` flags.
984+
- `flushEvery`: Flushes the output buffer after a given number of items.
985+
986+
For best results, disable buffered ORM results and avoid collection operations
987+
that materialize the entire dataset before streaming.
988+
930989
### Setting the Character Set
931990

932991
`method` Cake\\Http\\Response::**withCharset**(string $charset): static

docs/en/views/json-and-xml-views.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,29 @@ $this->viewBuilder()
200200
->setOption('jsonOptions', JSON_FORCE_OBJECT);
201201
```
202202

203+
### Streaming Large JSON Payloads
204+
205+
`JsonView` is a good fit when your action can serialize the complete payload in
206+
memory. For large result sets, use `Cake\Http\Response\JsonStreamResponse`
207+
instead and return it directly from the controller:
208+
209+
```php
210+
use Cake\Http\Response\JsonStreamResponse;
211+
212+
public function export()
213+
{
214+
$query = $this->Articles->find()
215+
->enableHydration(false)
216+
->bufferResults(false);
217+
218+
return new JsonStreamResponse($query);
219+
}
220+
```
221+
222+
See [Streaming Large JSON Responses](../controllers/request-response.md#streaming-large-json-responses)
223+
for the available options, including NDJSON output, item transforms, and
224+
flushing controls.
225+
203226
### JSONP Responses
204227

205228
When using `JsonView` you can use the special view variable `jsonp` to

0 commit comments

Comments
 (0)