google/gax
Google API Core for PHP (gax-php) provides shared infrastructure for Google API clients, especially generated libraries using gRPC. Includes helpers for retries, pagination/page streaming, long-running operations, and Google API conventions. Requires PHP 8.1+.
Installation:
composer require google/gax
Requires PHP 8.1+ and pecl install protobuf.
First Use Case:
Integrate with a Google API client (e.g., Cloud Storage, Pub/Sub) that uses google/gax under the hood. Example:
use Google\Cloud\Storage\StorageClient;
$storage = new StorageClient();
$buckets = $storage->buckets(); // Leverages gax for pagination/retry
Key Entry Points:
StorageClient).RetrySettings or ExponentialBackoff.PageStream for paginated responses or BidiStream for bidirectional streams.Use ClientOptionsTrait to customize clients:
use Google\ApiCore\ClientOptionsTrait;
class CustomClient {
use ClientOptionsTrait;
public function __construct() {
$this->clientOptions = [
'apiKey' => 'YOUR_API_KEY',
'universeDomain' => 'googleapis.com', // For multi-tenant environments
];
}
}
Extend functionality with middleware (e.g., logging, metrics):
use Google\ApiCore\ApiMiddleware;
use Google\ApiCore\Middleware\TransportCallMiddleware;
$client = new StorageClient();
$client->prependMiddleware(new TransportCallMiddleware(function ($call) {
// Log request/response
return $call->proceed();
}));
Configure retries for transient failures:
use Google\ApiCore\Retry\RetrySettings;
$retrySettings = new RetrySettings([
'maxAttempts' => 3,
'initialBackoff' => 100, // ms
'maxBackoff' => 5000, // ms
]);
$client->setRetrySettings($retrySettings);
Handle paginated or bidirectional streams:
// Paginated response (e.g., list buckets)
foreach ($client->buckets()->list() as $bucket) {
// Process each bucket
}
// Bidirectional stream (e.g., Pub/Sub)
$stream = $client->subscribe($topic);
$stream->onMessage(function ($message) {
// Handle message
});
Access detailed error info:
try {
$client->deleteBucket('bucket-name');
} catch (ApiException $e) {
$errorDetails = $e->getErrorDetails(); // Structured error metadata
$statusCode = $e->getStatus()->getCode();
}
Middleware Order:
prependMiddleware() for early-stage processing (e.g., auth).Universe Domain:
universeDomain in ClientOptions to avoid misrouted requests.Protobuf Serialization:
Serializer. Use Serializer::register() for non-standard types.Emulator Support:
InsecureCredentialsWrapper or InsecureRequestBuilder to bypass TLS:
$client->setCredentialsWrapper(new InsecureCredentialsWrapper());
Deprecated Methods:
GapicClientTrait::modifyClientOptions() in newer versions; use ClientOptionsTrait instead.Enable Logging: Add a middleware to log requests/responses:
$client->prependMiddleware(new ApiMiddleware(function ($call) {
error_log('Request: ' . print_r($call->getRequest(), true));
return $call->proceed();
}));
Retry Debugging:
Set RetrySettings with maxAttempts: 1 to test failure paths:
$retrySettings = new RetrySettings(['maxAttempts' => 1]);
$client->setRetrySettings($retrySettings);
Protobuf Validation:
Use google/protobuf's built-in validation:
$request = new MyRequest();
$request->setField('value');
if (!$request->isInitialized()) {
throw new \RuntimeException('Invalid protobuf request');
}
Custom Transports:
Implement TransportInterface for non-gRPC backends (e.g., REST):
use Google\ApiCore\Transport\TransportInterface;
class CustomTransport implements TransportInterface {
public function call($request, $metadata = []) {
// Implement custom logic
}
}
Serializer Extensions:
Extend Serializer for custom protobuf types:
use Google\ApiCore\Serializer;
Serializer::register('MyCustomType', function ($value) {
return new MyCustomType($value);
});
API Key Rotation:
Dynamically update apiKey in ClientOptions without recreating the client:
$client->setClientOptions(['apiKey' => 'NEW_API_KEY']);
universeDomain can be set via GAX_UNIVERSE_DOMAIN env var (fallback: googleapis.com).CredentialsWrapper to avoid surprises.GapicClientTrait::modifyClientOptions() are deprecated in favor of ClientOptionsTrait::setClientOptions().Serializer caches compiled protobuf schemas. For high-throughput apps, preload schemas during bootstrap:
$serializer = new Serializer();
$serializer->compileSchema(file_get_contents('schema.proto'));
PageStream::limit() to avoid memory issues with large datasets:
$stream = $client->listObjects($bucket)->limit(1000);
How can I help you explore Laravel packages today?