geocoder-php/locationiq-provider
LocationIQ provider for the Geocoder PHP library, adding geocoding and reverse geocoding through LocationIQ's API. Drop it into any Geocoder setup to resolve addresses to coordinates and coordinates back to addresses.
Architecture fit. This is a thin, single-purpose adapter: it implements the geocoder-php/geocoder provider contract for LocationIQ's forward and reverse geocoding endpoints. Two consequences matter for a Laravel product:
geocoder-php/geocoder (provider registry, Address/Coordinates value objects, query/limit/locale options). The package itself is a few hundred lines of request building and response mapping. That is a good trade — the vendor-specific surface you own is small, and the escape hatch (swap providers) is real.LocationIQServiceProvider, no publishable config, no facade. You write ~10–20 lines of container binding yourself. This is fine architecturally (nothing to fight, nothing to upgrade) but means the integration is your code, and the "package" does not reduce your integration ownership as much as a Laravel-native wrapper (e.g. geocoder-laravel) would.curl call. For a TPM, that is an observability dividend and removes a dependency-conflict category.Integration feasibility. Low effort, well within a single sprint. composer require geocoder-php/geocoder geocoder-php/locationiq-provider, an API key in the environment, a singleton binding, and a small service class wrapping forward/reverse calls. No schema changes, no migrations, no background workers required for a v1. The main friction is version alignment, not code: the provider's 1.5.0 release exists specifically to support Geocoder 5, and the 1.4.x line targets Geocoder 4. You must pin the pair deliberately rather than letting ^ constraints resolve.
Technical risk. The dominant risks are vendor and maintenance, not the code:
| Risk | Severity | Notes / Mitigation |
|---|---|---|
| Upstream maturity signals | Medium | 5 stars, 0 dependents. The code may be fine, but the community safety net is thin. Mitigate by treating the adapter as ~200 lines you could vendor or fork in an afternoon; confirm you are comfortable doing that. |
| Maintenance velocity | Medium | Release history is sparse and milestone-shaped (PHP 8.0, PHP 8.1, Geocoder 5, PSR-18) rather than continuous. Historically each minor bumped the PHP floor (7.2 → 7.3 → 8.1). Expect runtime support to move in steps; budget a routine upgrade task per PHP minor. |
| Vendor concentration | Medium-High | All geocoding value is LocationIQ's API: quota, accuracy, uptime, pricing, ToS on storing results. The package cannot mitigate any of this. |
| Version drift | Medium | Geocoder 4 vs 5 and PHP floor constraints will silently produce a broken composer resolution if you add another geocoder provider later. |
| Error semantics | Low-Medium | LocationIQ returns empty result sets and ambiguous "no match" cases; the wrapper maps these to empty collections. Callers that assume ->first() is non-null will null-pointer in production. |
| Data/compliance | Medium | Addresses are PII. LocationIQ is OSM-derived; confirm GDPR/DPA posture, retention rules, and whether caching geocoded results in your DB is permitted under their terms. |
Key questions to resolve before committing:
Stack fit. Laravel 9/10/11 on PHP 8.1+. The provider slots in cleanly and requires nothing of your data layer. Recommended shape:
LocationIQ provider and a Geocoder instance as singletons in a dedicated GeocodingServiceProvider.GeocodingService::geocode(string): ?Coordinates) to feature code. Never let controllers or models touch Geocoder\Provider\LocationIQ\* directly — that is what makes the vendor swap a one-file change later.Coordinates, normalized address array), not raw Geocoder\Model\Address objects, at the boundary.Migration path. Three plausible entry points:
normalizeCity behavior), so golden-file tests comparing old vs new output on a sample of real addresses are essential before cutover.Compatibility notes.
geocoder-php/geocoder and the provider together; do not rely on floating constraints.geocoder-laravel (the community Laravel wrapper) can host this provider if you want config publishing and a facade; evaluate whether that convenience is worth an extra dependency versus 20 lines of your own binding.Sequencing.
Maintenance. Low absolute code maintenance, non-trivial tracking maintenance. You own the wiring layer, the caching policy, the error-handling policy, and the upgrade cadence against two dependencies plus one external API. Releases are infrequent, which cuts churn but also means upstream can lag on new PHP versions — budget a small, recurring task (~1 day/quarter) to check composer outdated, PHP floor compatibility, and LocationIQ's API changelog. Because the adapter is small, "fork and maintain internally" is a credible contingency and should be written into the risk register as such rather than treated as a crisis.
Support. Two tiers, both external:
Build an internal runbook before launch: how to rotate the API key, what a 429 means and who to page, how to inspect a failed geocode, and how to fail open vs fail closed. "Fail open" (accept the user's raw address, flag it) is usually the right product default for address entry — decide this explicitly, not by accident.
Scaling. The app tier scales horizontally without thought; the quota is the only real ceiling. Key characteristics:
Failure modes to design for:
| Failure | User-visible symptom | Mitigation |
|---|---|---|
| Invalid/rotated API key (401) | Every geocode fails | Key in secret manager, rotation runbook, startup smoke check |
| Rate limit / quota exhausted (429) | Intermittent onboarding failures | Cache, queue, alert on 429 rate, soft-fail to manual entry |
| LocationIQ outage (5xx/timeout) | Slow pages, timeouts | Hard timeout ≤3s, circuit breaker, optional fallback provider |
| Empty/ambiguous result | Silent null coordinates downstream |
Explicit "unverified" state on the domain model; never store nulls as 0,0 |
| Bad address data (typos, non-standard formats) | Poor match quality blamed on your product | Surface confidence/quality, allow manual pin-drop correction |
| Upstream schema/endpoint change | Mapping breaks after a dependency bump | Golden-file contract tests in CI; pin versions and upgrade deliberately |
Ramp-up. Genuinely low: a mid-level Laravel developer is productive in half a day. The documentation is the changelog plus LocationIQ's own API docs, so plan for the team's knowledge to come from your runbook and tests, not upstream. The main ramp-up cost is not the package — it is the product and legal groundwork around it: quota sizing, PII handling, and deciding what the UI does when geocoding is uncertain or unavailable.
How can I help you explore Laravel packages today?