在 Guzzle 6 中读取大型 JSON API 响应的正确方法是什么?

What is the correct way to read a large JSON API response in Guzzle 6?

我目前有以下 Guzzle 6 实现 returning 包含用户数据的 JSON 数据流:

$client = new GuzzleHttp\Client([
        'base_uri' => 'https://www.apiexample.com',
        'handler' => $oauthHandler,
        'auth'    => 'oauth',
        'headers' => [
            'Authorization' => 'Bearer xxxxxxxxxxxxxx',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
]);

$res = $client->post('example');
$stream = GuzzleHttp\Psr7\stream_for($res->getBody());

JSON 回复如下:

{
    "name": "Users",
    "record": [
        {
            "title": "Consulting",
            "_name": "Users",
            "end date": "07/03/2020",
            "session number": "1",
            "start date": "09/02/2019",
            "course id": "2900",
            "first name": "John",
            "unique user number": "123456",
            "time": "08 AM",
            "last name": "Doe",
            "year": "19-20",
            "location name": "SD"
        },
        .........
     ],
     "@extensions": "activities,corefields,u_extension,u_stu_x,s_ncea_x,s_stu_crdc_x,c_locator,u_userfields,s_edfi_x"
 }

对于许多使用不同 API 端点的客户端,这是 运行。其中许多 return 用户太多,整个 JSON 响应无法一次加载到 RAM 中,这就是我使用流的原因。

可能有一种方法可以通过多次调用以增量方式获取 API 到 return 块。但是从我从 API 的开发人员那里得到的一切来看,这似乎是为了作为一个流式响应来使用的。

我不熟悉必须像这样流式传输 API 响应,想知道遍历记录的正确方法是什么?查看 Guzzle 6 文档,似乎通过选择字符串中的数字 x 字符并获取该小节来进行迭代:

http://docs.guzzlephp.org/en/stable/psr7.html#streams

use GuzzleHttp\Psr7;

$stream = Psr7\stream_for('string data');
echo $stream;
// string data
echo $stream->read(3);
// str
echo $stream->getContents();
// ing data
var_export($stream->eof());
// true
var_export($stream->tell());
// 11

我可能会写一些东西来通过模式匹配来解析子部分中的字符串,并在我通过响应移动时将数据增量写入磁盘。但这似乎很容易出错,并且是 Guzzle 6 的一部分。

你能提供一个例子说明这样的事情应该如何工作或指出我可能遗漏了什么吗?

非常感谢,谢谢!

But it seems like that would be error prone and something that would be part of Guzzle 6.

不是,Guzzle 是一个 HTTP 客户端,它与解析不同的响应格式无关。

您需要的是 JSON 流解析器。请看一下this SO question, and also at the libraries: https://github.com/salsify/jsonstreamingparser, https://github.com/clue/php-json-stream, https://github.com/halaxa/json-machine

在 Guzzle 中,您将有 2 种可能性:

  • 手动读取响应流(就像您目前所做的那样),但这可能需要与 JSON 流解析器手动集成
  • 将整个响应流式传输到临时文件(参见 "sink" request option)并稍后使用 JSON 流式解析器读取此文件,所有库都应支持此操作。