使用 Guzzle 6 创建异步 json 请求池以发送到 API 端点的正确方法是什么?

What's the correct way to use Guzzle 6 to create pool of asynchronous json requests to send to API endpoints?

我的 objective 是使用 Guzzle 6 创建一个 PUT json 数据的异步请求池。然后监控每个 $promise success/failure.

为了与我的 POOL 代码示例进行比较,以下对 $client->request() 的单个请求将第 3 个参数转换为编码 json,然后添加内容类型:application/json。 **

$client = new Client([
    'base_uri' => BASE_URL . 'test/async/', // Base URI is used with relative requests
    'timeout'  => 0, // 0 no timeout for operations and watching Promises
]);

$response = $client->request('PUT', 'cool', ['json' => ['foo' => 'bar']]);

在接收 API 端点上,我可以通过执行以下操作从上面的单个请求中读取 json:

$json = file_get_contents('php://input');
$json = json_decode($json, true);

使用 concurrent requests example in the docs, for creating a Pool of asynchronous requests using new Request(),我希望可以使用与单个 $client 中相同的参数(方法、url 端点、json 标志) ->request() 上面的例子。但是,yield new Request() 不像 $client->request() 那样处理第 3 个 json 参数。 从我的 Pool 代码调用以正确设置 json 和内容类型的正确 Guzzle 函数是什么?或者是否有更好的方法来创建大量异步请求并监控其结果?

POOL 代码示例:

$this->asyncRequests = [
    [
        'endpoint' => 'cool'
    ],
    [
        'endpoint' => 'awesome'
    ],
    [
        'endpoint' => 'crazy'
    ],
    [
        'endpoint' => 'weird'
    ]
];

$client = new Client([
    'base_uri' => BASE_URL, // Base URI is used with relative requests
    'timeout'  => 0 // 0 no timeout for operations and watching Promises
]);

$requests = function ($asyncRequests) {
    $uri = BASE_URL . 'test/async/';

    foreach ($asyncRequests as $key => $data) {
        yield new Request('PUT', "{$uri}{$data['endpoint']}", ['json' => ['foo' => 'bar']]);
    }
};

$pool = new Pool($client, $requests($this->asyncRequests), [
    'concurrency' => 10,
    'fulfilled' => function ($response, $index) {
        $this->handleSuccessPromises($response, $index);
    },
    'rejected' => function ($reason, $index) {
        $this->handleFailurePromises($reason, $index);
    },
]);

$promise = $pool->promise(); // Initiate the transfers and create a promise

$promise->wait(); // Force the pool of requests to complete.

希望其他人会跳进来让我知道是否有更正确的方法来完成我的 objective,但是在 Guzzle 中深入了解之后我意识到了新的 Request()的第三个参数正在寻找 header 信息,第四个参数正在寻找 body。所以下面的代码使用池工作:

foreach ($syncRequests as $key => $headers) {
    yield new Request('PUT', "{$uri}{$headers['endpoint']}", ['Content-type' => 'application/json'], json_encode(['json' => ['nonce' => $headers['json']]]));
}

Also in docs for Psr7\Request

如果您想要完全控制,请不要在池中使用 Request() 对象。相反,通过让池的生成器产生一个启动请求的可调用函数来自己启动请求。这使您可以完全控制所有选项。这是一个正确的代码示例: