google/gax
Google API Core for PHP (gax-php) provides shared components used by generated Google Cloud API clients, including gRPC-based call handling, retries, timeouts, and page streaming. Designed for PHP 8.1+ and Google API conventions; most users won’t call it directly.
Installation
composer require google/gax
Requires PHP 8.1+ and protobuf extension.
First Use Case: Basic API Client
Most Laravel developers will interact with gax-php indirectly via Google Cloud client libraries (e.g., google/cloud-storage). However, for direct use:
use Google\ApiCore\ApiException;
use Google\ApiCore\Gapic\GapicClientTrait;
use Google\ApiCore\Gapic\Rest\RestClient;
class MyClient extends RestClient {
use GapicClientTrait;
protected function modifyClientOptions(): void {
$this->clientOptions->setApiKey('YOUR_API_KEY');
}
}
Key Entry Points
GapicClientTrait: Core trait for Google API clients (retry, pagination, auth).ApiException: Standardized error handling for Google API errors.Workflow: Configure clients with environment-aware defaults.
// config/google.php
return [
'client_options' => [
'api_key' => env('GOOGLE_API_KEY'),
'universe_domain' => env('GOOGLE_UNIVERSE_DOMAIN', 'googleapis.com'),
],
];
// In your service
$client = new MyClient([
'clientOptions' => config('google.client_options'),
]);
Pattern: Extend request/response pipelines (e.g., add headers, logging).
use Google\ApiCore\Gapic\Middleware\MiddlewareInterface;
class LoggingMiddleware implements MiddlewareInterface {
public function handle($request, callable $next) {
Log::debug('Outgoing request:', $request->getData());
return $next($request);
}
}
// Register in client
$client->prependMiddleware(new LoggingMiddleware());
Use Case: Handle large datasets efficiently.
// Paginated list (auto-handled by GapicClientTrait)
$results = $client->listObjects(['pageSize' => 100]);
foreach ($results as $page) {
foreach ($page->getItems() as $item) {
// Process item
}
}
// Bidirectional streaming (e.g., Pub/Sub)
$stream = $client->streamingCall(['callback' => fn($response) => Log::info($response)]);
Pattern: Leverage ApiException for structured errors.
try {
$client->callApi();
} catch (ApiException $e) {
$errorDetails = $e->getErrorDetails(); // Structured error metadata
Log::error('Google API Error:', $errorDetails);
throw new \RuntimeException('Failed to call API', 0, $e);
}
Pattern: Use emulators for local development.
// Configure emulator in tests
$client = new MyClient([
'clientOptions' => [
'hasEmulator' => true,
],
]);
Middleware Order Matters
prependMiddleware() adds middleware before existing middleware. Use appendMiddleware() for post-processing.Protobuf Version Conflicts
google/protobuf is pinned to ^5.0 (gax-php requires v5+).composer.json and run composer update google/protobuf.Universe Domain Misconfiguration
googleapis.com. Override via clientOptions or env var GOOGLE_UNIVERSE_DOMAIN.Emulator-Specific Quirks
InsecureCredentialsWrapper bypasses auth. Never use in production.hasEmulator: true in clientOptions for local testing.Deprecated Methods
GapicClientTrait::setApiKey() (use modifyClientOptions() instead).phpstan to catch deprecated calls.$client->getOptions()->setLoggingOptions([
'logLevel' => \Google\ApiCore\LoggingOptions::LOG_LEVEL_DEBUG,
]);
TransportCallMiddleware to log gRPC/REST payloads:
$client->prependMiddleware(new class implements MiddlewareInterface {
public function handle($request, callable $next) {
Log::debug('Raw request:', [
'method' => $request->getMethod(),
'data' => $request->getData(),
]);
return $next($request);
}
});
Custom Serialization
Override Serializer for non-standard protobuf types:
use Google\ApiCore\Serializer;
class CustomSerializer extends Serializer {
protected function encodeCustomType($value): string {
// Custom logic
}
}
Transport-Specific Logic
Extend TransportOptions for custom HTTP/gRPC behavior:
$client->getOptions()->setTransportOptions([
'grpc' => [
'timeout' => 30.0, // Custom timeout
],
]);
Operation Polling
For long-running operations, use OperationResponse:
$operation = $client->startOperation(['request' => $data]);
$response = $operation->waitUntilComplete();
AppServiceProvider:
$this->app->singleton(MyClient::class, fn($app) => new MyClient([
'clientOptions' => $app['config']['google.client_options'],
]));
.env for sensitive config:
GOOGLE_API_KEY=your_key_here
GOOGLE_UNIVERSE_DOMAIN=googleapis.com
dispatch(new ProcessGoogleOperation($client, $request));
How can I help you explore Laravel packages today?