Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 59 additions & 0 deletions docs/en/controllers/request-response.md
Original file line number Diff line number Diff line change
Expand Up @@ -927,6 +927,65 @@ $stream = new CallbackStream(function () use ($img) {
$response = $response->withBody($stream);
```

### Streaming Large JSON Responses

`class` **Cake\\Http\\Response\\JsonStreamResponse**

When you need to send a large JSON response, `JsonStreamResponse` lets you
stream each item instead of building the entire payload in memory first. This
is useful for large exports, APIs backed by database cursors, or any response
where buffering the full result would be wasteful.

```php
use Cake\Http\Response\JsonStreamResponse;

public function index()
{
$articles = $this->fetchTable('Articles')
->find()
->select(['id', 'title', 'created'])
->enableHydration(false)
->bufferResults(false);

return new JsonStreamResponse($articles);
}
```

`JsonStreamResponse` sets the `Content-Type` header to `application/json` by
default and disables proxy buffering with the `X-Accel-Buffering: no` header.

If you need newline-delimited JSON instead of a JSON array, use the
`JsonStreamResponse::FORMAT_NDJSON` format:

```php
use Cake\Http\Response\JsonStreamResponse;

public function stream()
{
$query = $this->fetchTable('Articles')
->find()
->select(['id', 'title'])
->enableHydration(false)
->bufferResults(false);

return new JsonStreamResponse($query, [
'format' => JsonStreamResponse::FORMAT_NDJSON,
]);
}
```

You can customize the output with these options:

- `root`: Wraps the payload in a top-level object.
- `envelope`: Adds additional top-level keys alongside the streamed data.
- `dataKey`: Renames the streamed collection key when using `root`.
- `transform`: Applies a callback to each item before encoding it.
- `flags`: Sets the `json_encode()` flags.
- `flushEvery`: Flushes the output buffer after a given number of items.

For best results, disable buffered ORM results and avoid collection operations
that materialize the entire dataset before streaming.

### Setting the Character Set

`method` Cake\\Http\\Response::**withCharset**(string $charset): static
Expand Down
23 changes: 23 additions & 0 deletions docs/en/views/json-and-xml-views.md
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,29 @@ $this->viewBuilder()
->setOption('jsonOptions', JSON_FORCE_OBJECT);
```

### Streaming Large JSON Payloads

`JsonView` is a good fit when your action can serialize the complete payload in
memory. For large result sets, use `Cake\Http\Response\JsonStreamResponse`
instead and return it directly from the controller:

```php
use Cake\Http\Response\JsonStreamResponse;

public function export()
{
$query = $this->Articles->find()
->enableHydration(false)
->bufferResults(false);

return new JsonStreamResponse($query);
}
```

See [Streaming Large JSON Responses](../controllers/request-response.md#streaming-large-json-responses)
for the available options, including NDJSON output, item transforms, and
flushing controls.

### JSONP Responses

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