google-cloud-php icon indicating copy to clipboard operation
google-cloud-php copied to clipboard

fix(Firestore): use x-goog-request-params header

Open bshaffer opened this issue 8 months ago • 1 comments

TODO:

  • [ ] call listen APIs in system tests and/or using the emulator to ensure the behavior functions as expected

bshaffer avatar Apr 29 '25 20:04 bshaffer

This requires more research, mostly because when calling the listen methods (which are the methods where this is necessary), the API throws an exception because the routing headers aren't supplied

Call failed with message: Missing required http header ('google-cloud-resource-prefix' or 'x-goog-request-params') or query param 'database'.

I can fix this by supplying the headers parameter directly to the listen call:

$stream = $firestoreClient->listen([
    'headers' => [
        'x-goog-request-params' => [
            'database=' . $database
        ]
    ]
]);

But this is non-intuitive and error-prone. With minimal changes to the GAPIC layer, we could make this work by only supplying the "database" option:

$stream = $firestoreClient->listen(['database' => $database]);

And follow this up by generating a "PHPDoc" explaining the database option's usage, which would hopefully be enough to make this discoverable and implementable by developers:

    /**
     * Listens to changes. This method is only available via gRPC or WebChannel
     * (not REST).
     *
     * @example samples/V1/FirestoreClient/listen.php
     *
     * @param array $callOptions {
     *     Optional.
     *
+    *     @type string $datbase
+    *           Set the database of the call, to be added as a routing header
     *     @type int $timeoutMillis
     *           Timeout to use for this call.
     * }
     *
     * @return BidiStream
     *
     * @throws ApiException Thrown if the API call fails.
     */
    public function listen(array $callOptions = []): BidiStream
    {
+       $requestParamHeaders = [];
+       if (isset($callOptions['database'])) {
+           $requestParamHeaders['database'] = $callOptions['database'];
+       }
+       $requestParams = new \Google\ApiCore\RequestParamsHeaderDescriptor($requestParamHeaders);
+       $callOptions['headers'] = isset($optionalArgs['headers']) ? array_merge($requestParams->getHeader(), $callOptions['headers']) : $requestParams->getHeader();
        return $this->startApiCall('Listen', null, $callOptions);
    }

bshaffer avatar May 20 '25 22:05 bshaffer

LGTM

viacheslav-rostovtsev avatar Aug 27 '25 21:08 viacheslav-rostovtsev