google/analytics-data
Idiomatic PHP client for Google Analytics Data, supporting REST and gRPC. Install via Composer, authenticate with Google Cloud, and query analytics reports with ready-made client classes.
Architecture fit
This is a low-level, protobuf-generated API client for the Google Analytics Data API (GA4 reporting), published as a component of the google-cloud-php monorepo. It is not a Laravel package: there is no service provider, config file, facade, queue integration, or caching layer. In a Laravel codebase it occupies the same slot as an SDK — a transport and typed request/response layer that our application must wrap in its own domain services. That is a workable and arguably preferable architecture (thin adapter + our own DTOs), but it means the integration effort is "build a small internal reporting module," not "install and configure."
The surface we actually need is narrow: BetaAnalyticsDataClient with runReport, runPivotReport, and runRealtimeReport, plus the Filter/Dimension/Metric/OrderBy message types. The v1alpha surface (report tasks, audience lists/exports, property quota snapshots) is pre-GA and should be excluded from the initial design; it is where most of the churn in the changelog originates.
Integration feasibility
Composer installation is trivial and the auth model is standard Google: Application Default Credentials, or an explicit service-account key, or workload identity. Both REST/HTTP1.1 and gRPC transports are supported. The main feasibility gate is environmental, not code: gRPC requires ext-grpc and ext-protobuf, which are frequently absent on shared hosting and are not part of a default Laravel Sail/Forge image. The REST transport is a viable fallback and should be the default decision unless we have a measured need for gRPC.
The second gate is credentials handling. A long-lived service-account JSON in the repository or in an env var is a security incident waiting to happen; we should prefer ADC/workload identity where the app runs on GCP, and a secrets manager otherwise, with the service account scoped read-only to specific GA4 properties.
Technical risk
ResponseMetaData (sampling metadata, subjectToThresholding) and surface it in the UI or logs, dashboards will quietly report wrong numbers. This is the highest-impact product risk in the package.orderBy fields are rejected at request time with 400s. This pushes validation into our code and makes "user-configurable reports" a much larger feature than it looks.Key questions
ext-grpc available — or do we commit to REST?spatie/laravel-analytics) that already wraps this package?gax/protobuf constraints may conflict?Stack fit
PHP 8.x + Laravel 10/11/12, installed via Composer alongside the existing dependency set. The client should be bound as a singleton in a service provider (client construction is relatively expensive and carries channel/connection state), injected into a dedicated AnalyticsReportService, and never instantiated ad hoc inside controllers. Configuration belongs in config/analytics.php with property IDs, credential source, transport, timeout, and retry settings; secrets stay in the environment or secret manager.
We should wrap the generated messages in our own request objects and return our own result DTOs. This is the single most valuable design decision: it isolates the rest of the app from 0.x breaking changes and from protobuf types leaking into controllers, jobs, and Blade views.
Migration path
There is no Universal Analytics migration here — UA reporting is retired, so GA4 Data API is the only supported path; the realistic migration is from CSV exports, the GA4 web UI, or an existing community wrapper to this package. If spatie/laravel-analytics is already in the codebase, it is wrapping this same client; the decision is whether to keep that abstraction or replace it with a thinner in-house one. Replacing a working wrapper is rarely worth it unless we need pivot reports, realtime, or fine-grained retry/timeout control.
Compatibility
Verify PHP constraint and ext-grpc/ext-protobuf availability on every target environment before committing. Run composer why-not against the existing Google Cloud packages to detect gax/protobuf version conflicts. Pin an exact minor (~0.28.0) rather than a caret on 0.x, and commit the lockfile. Prefer --prefer-dist and ensure CI installs the same extensions as production, or the transport decision will diverge silently between environments.
Sequencing
runReport over REST, confirm extension availability and composer resolution.AnalyticsReportService, error mapping, response DTOs including sampling/thresholding flags.Maintenance
Low code-maintenance, moderate dependency-maintenance. The generated code is not ours to maintain, but the 0.x cadence means we must actively track releases. Establish a monthly dependency-review cadence and a standing task to read the google-cloud-php changelog rather than the individual repo. Automate composer update google/analytics-data --with-dependencies in a branch with the reporting test suite as the gate; never auto-merge. Budget a small recurring allowance for the eventual 1.0 migration and any proto behavior changes.
Support
Support flows to the google-cloud-php monorepo issue tracker, not this repository — the README is explicit about that. There is no Laravel community to lean on for this specific integration, so an internal runbook is mandatory: how to rotate credentials, how to add a property, how to interpret a 403 vs. 429 vs. 400, and where sampling is surfaced. Expect to own the abstraction layer entirely.
Scaling
Scaling is a quota-engineering problem. Cache aggressively — historical date ranges are immutable, so cache keys should include property, date range, dimensions, metrics, and filters, with long TTLs for closed periods and short TTLs only for "today" and realtime. Push report generation into queued jobs to smooth bursts, cap concurrency per property, and back off with jitter on 429/503. If volume outgrows quota, the strategic answer is the BigQuery export rather than more API calls. Watch response row counts and set limit/offset deliberately; large unpaginated reports are a latency and memory risk.
Failure modes
ext-grpc after an infrastructure change → fatal on client construction (mitigated by explicit transport config and a startup health check).Ramp-up A mid-level Laravel developer can produce a working report in a day or two; production-grade integration (caching, retries, error taxonomy, observability, validation) is roughly one to two weeks. The steeper curve is GA4 domain knowledge — dimension/metric compatibility, property structure, attribution and thresholding semantics, quota mechanics — which is a product/analytics skill, not a PHP one. Plan for an analytics-literate partner during design, and keep the reporting definitions documented outside the code, because they will change more often than the integration does.
How can I help you explore Laravel packages today?