'How do I configure default query parameters with Guzzle 6?

Migrating from 5 to 6, and I've run into a snag and can't find the relevant docs.

Guzzle docs here, http://guzzle.readthedocs.io/en/latest/quickstart.html#creating-a-client, site that we can add "any number of default request options".

I want to send "foo=bar" with every request. E.g.:

$client = new Client([
    'base_uri' => 'http://google.com',
]);

$client->get('this/that.json', [
    'query' => [ 'a' => 'b' ],
]);

This will generate GET on http://google.com/this/that.json?a=b

How do I modify the client construction so that it yields:

http://google.com/this/that.json?foo=bar&a=b

Thanks for your help!



Solution 1:[1]

Alright, so far, this works here:

        $extraParams = [
            'a' => $config['a'],
            'b' => $config['b'],
        ];

        $handler = HandlerStack::create();
        $handler->push(Middleware::mapRequest(function (RequestInterface $request) use ($extraParams) {

            $uri  = $request->getUri();
            $uri .= ( $uri ? '&' : '' );
            $uri .= http_build_query( $extraParams );

            return new Request(
                $request->getMethod(),
                $uri,
                $request->getHeaders(),
                $request->getBody(),
                $request->getProtocolVersion()
            );
        }));

        $this->client = new Client([
            'base_uri' => $url,
            'handler' => $handler,
            'exceptions' => false,
        ]);

If anyone knows how to make it less sinister-looking, I would say thank you!

Solution 2:[2]

I found a nice solution here.

Basically, anything defined in the first array of arguments, become part of the config for the client.

this means you can do this when initialising:

$client = new Client([
    'base_uri' => 'http://google.com',
    // can be called anything but defaults works well
    'defaults' => [
        'query'  => [
            'foo' => 'bar',
        ]
    ]
]);

Then, when using the client:

$options = [
    'query'  => [
        'nonDefault' => 'baz',
    ]
];

// merge non default options with default ones
$options = array_merge_recursive($options, $client->getConfig('defaults'));

$guzzleResponse = $client->get('this/that.json', $options);

It's woth noting that the array_merge_recursive function appends to nested arrays rather than overwrites. If you plan on changing a default value, you'll need a different utility function. It works nicely when the default values are immutable though.

Solution 3:[3]

A "less sinister-looking" example based on the answer by @Saeven and the comment from @VladimirPak.

        $query_defaults = [
            'a' => $config['a'],
            'b' => $config['b'],
        ];

        $handler = \GuzzleHttp\HandlerStack::create();
        $handler->push(\GuzzleHttp\Middleware::mapRequest(function (\Psr\Http\Message\RequestInterface $request) use ($query_defaults) {

            $query = \GuzzleHttp\Psr7\Query::parse($request->getUri()->getQuery());
            $query = array_merge($query_defaults, $query);

            return $request->withUri($request->getUri()->withQuery(\GuzzleHttp\Psr7\Query::build($query)));

        }));

        $this->client = new \GuzzleHttp\Client([
            'base_uri' => $url,
            'handler' => $handler,
            'exceptions' => false,
        ]);

I'm not sure how less sinister-looking it is though. lol

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Saeven
Solution 2
Solution 3 Ryan Worth