In modern web development, dealing with real-time or streaming data efficiently is crucial, especially when interacting with APIs that serve data in chunks, such as streaming logs, telemetry, or live updates. Laravel's HTTP client, built on top of Guzzle, provides a clean and expressive interface for handling these scenarios.

Below, we’ll break down a PHP script that demonstrates how to handle streamed responses from an API endpoint using Laravel's HTTP client.

$stream = Http::throw()
    ->accept('application/x-ndjson')
    ->asJson()
    ->withOptions(['stream' => true])
    ->post($endpoint, $requestData)
    ->toPsrResponse()
    ->getBody();

$buffer = '';

while ($stream->eof() === false) {
    $char = $stream->read(1);

    $buffer .= $char;
    if ($char === "\n") {
        $line = trim($buffer);
        $buffer = '';

        if (!empty($line)) {
            dump($line);
        }
    }
}

The HTTP client is configured to handle streamed responses. It ensures that errors are thrown for non-2xx responses, sets the Accept header to expect application/x-ndjson (new-line delimited JSON), and sends the request body as JSON. The critical option here is ['stream' => true], enabling response streaming to handle data incrementally.

Once the response is received, the stream is processed character by character. Each character is appended to a buffer until a newline (\n) character is detected. At that point, the buffer is trimmed, and the resulting line is outputted using dump($line). The newline indicates that we received a complete blo of JSON data that can be processed. If the line is empty, it’s ignored.

This approach ensures memory efficiency and allows real-time processing of the streamed data. For example, log streams, telemetry data, or event feeds can be parsed and processed incrementally.

This pattern is powerful because it avoids loading the entire response into memory, making it ideal for large datasets or real-time updates. To handle potential issues, such as network interruptions or unexpected stream behavior, error handling and timeout configurations can further enhance this implementation.

Resources: