alexpechkarev/google-geocoder
PHP client for the Google Maps Geocoding API. Convert addresses into latitude/longitude coordinates and reverse geocode coordinates back into addresses with a simple, framework-agnostic interface for adding location lookup to your apps.
Architecture fit. The package is a thin, conventional Laravel wrapper: a service provider binds a client, a facade (GoogleGeocoder) exposes it, and a published config file holds the API key. It fits the Laravel idioms of its era (5.x, PHP 5.6–7.1) and imposes little architectural opinion — which is simultaneously its appeal and its risk. Because it sits directly behind a facade, call sites tend to be statically coupled to the package's namespace and response objects. For any codebase we intend to own for more than a year, this is the wrong seam: we want an internal Geocoder contract (address in, normalized result out) with the package as one adapter behind it.
Integration feasibility. The blocker is dependency age, not API design. With a last release of 2017-09-27, expect illuminate/support constraints in the ~5.x range and a Guzzle constraint that collides with the Guzzle 7 that ships with Laravel 8+. On a modern PHP 8.1+/Laravel 10/11 estate, composer require will likely fail resolution outright; forcing it with platform-req overrides trades a clean install for runtime fatal errors on untyped, possibly deprecated signatures. On a legacy Laravel 5 app it will install and work. Practically: feasible as-is for legacy, requires a fork for current stacks, and the fork is small enough that "replace" usually beats "maintain."
Technical risk.
extra.laravel), no PSR-18/PSR-17 abstraction. Each framework upgrade becomes a fork-and-patch exercise.OVER_DAILY_LIMIT, REQUEST_DENIED) has expanded. The wrapper's error handling predates this and likely surfaces Google payloads raw.Key questions for the requestor.
Stack fit. Clean fit for Laravel 5.1–5.5 on PHP 5.6–7.0. Poor fit for Laravel 8+ / PHP 8+. Treat "legacy app, low volume, short horizon" as the only green-light scenario for direct adoption.
Migration path. Three viable routes, in ascending order of preference:
geocoder-php/Geocoder with the Google Maps provider, or a ~200-line in-house client over Laravel's Http facade. The API is a single HTTPS GET with a key; the wrapper is not carrying meaningful complexity. Replacement removes the abandonment risk entirely for roughly the same effort as the fork.Compatibility notes to verify during the spike. Confirm the exact illuminate/support and guzzlehttp/guzzle constraints in composer.json; confirm the config key name and facade alias so call-site grep is exhaustive; confirm whether the client returns raw arrays or value objects, since that dictates the shape of the internal contract.
Sequencing.
Geocoder interface with a normalized result and a typed exception set covering ZERO_RESULTS, REQUEST_DENIED, OVER_QUERY_LIMIT, and transport failure.For a legacy-only scenario, execute steps 1–3 and stop; that alone caps the blast radius.
Maintenance. This is the dominant cost. There is no upstream to absorb framework or PHP upgrades, so every Laravel major becomes our work. Budget a named owner, a quarterly review of the fork against new Google API changes, and an explicit exit criterion. An unmaintained dependency also generates recurring noise in vulnerability scanning and procurement review; expect to justify it more than once.
Support. No vendor, no SLA, community-only issue tracker. Internal support means a runbook covering: how to rotate the API key, how to read Google's error payloads, what to do on quota exhaustion, and who to escalate to. The external support vector is the Google Geocoding API itself, whose deprecations and pricing changes arrive without warning and are the realistic source of incidents.
Scaling. The calls are synchronous HTTP with round-trip latency in the low hundreds of milliseconds. Google's standard limit is ~50 QPS, well above most product needs, but any bulk backfill must run through queued jobs with concurrency caps — do not geocode in a request cycle at volume. Cost scales linearly at roughly $5 per 1,000 requests against a monthly free allowance; a 100k/month workload is a real budget line, not a rounding error. A caching layer is the main lever but is bounded by Google's terms, so model the hit rate against realistic address-repeat rates before promising savings.
Failure modes to instrument.
REQUEST_DENIED — bad/rotated key or lapsed billing; fails closed and silently returns empty if the wrapper doesn't surface it.OVER_QUERY_LIMIT / OVER_DAILY_LIMIT — needs backoff and an alert, not a retry storm.ZERO_RESULTS — a valid outcome, not an error; conflating the two produces bad data quality and noisy pages.UNKNOWN_ERROR — transient, retryable with jitter.Ramp-up. Low for day-one productivity: a Laravel developer who knows facades can be shipping in an hour. The ramp-up risk is inverted — the package is easy enough that a team can adopt it without noticing it is eight years stale, and discover the constraint only at the next framework upgrade. Onboarding should include the abstraction boundary, the Google terms constraints on caching, and the cost model, not just the facade call.
How can I help you explore Laravel packages today?