Response Types

JSON, File, Streamed, and Event-Stream Responses

response()->json($data, 201) chooses the status of a JSON body, and response()->noContent() sends

  1. download($path, $name) sends a file as an attachment and file($path) sends it for display.

The streaming methods write output as it is produced:

A Server-Sent Events action in app/Http/Controllers/ExportController.phpPHP
return response()->eventStream(function (): Generator {
    foreach (Product::orderBy('stock')->limit(2)->cursor() as $p) {
        yield new StreamedEvent(event: 'stock', data: $p->only('sku', 'stock'));
        sleep(1);
    }
});
Output
$ ts() { while IFS= read -r l; do echo "[$(date -u +%T)] $l"; done; }    # arrival time
$ curl -sN $B/export/stock-events | ts
[07:50:17] event: stock
[07:50:17] data: {"sku":"BK-1005","stock":0}
[07:50:17]
[07:50:18] event: stock
[07:50:18] data: {"sku":"BK-1002","stock":3}
[07:50:18]
[07:50:19] event: update
[07:50:19] data: </stream>
[07:50:19]

Events arrived a second apart because each yield is flushed; stream() does the same for any generator. The final </stream> event tells EventSource or @laravel/stream-react to close. streamDownload() and streamJson() fed from a cursor() keep memory flat at any size. File responses mark themselves public, so a private header passed to download() needed ->setPrivate(). A stream holds a PHP-FPM worker while open; for mass pushes use Reverb 2,157 (Running Laravel Reverb).