NewWe open-sourced 50+ Laravel packages
Custom AI apps, agents and automation — Roundly ConsultingRoundly
All packages
Google Places for Laravel

Without the facade

The facade is the recommended default, not the only way in. In most packages there are three equivalent entry points — the facade, the manager injected through the constructor, and single-purpose action classes. google-places is a remote-API client, so it has no action classes: the client’s methods are the use cases. That leaves two:

  • The GooglePlaces facade — the shortest form.
  • The client, injected through the constructor — the same API with an explicit dependency and no static calls. The facade root is the RoundlyConsulting\GooglePlaces\Contracts\PlacesClient contract, bound as a singleton to the RoundlyConsulting\GooglePlaces\Places implementation.

Injecting the client

The facade and the contract resolve the same singleton, and GooglePlaces::fake() replaces both — so type-hint the contract, not the concrete Places class, in code you want to fake:

use RoundlyConsulting\GooglePlaces\Contracts\PlacesClient;

final class NearbyCafes
{
    public function __construct(private PlacesClient $places) {}

    public function __invoke(string $query): array
    {
        return $this->places->textSearch($query)->all();
    }
}

Handles built by an injected client call back into that client, so they are faked too:

use RoundlyConsulting\GooglePlaces\Contracts\PlacesClient;

final class PlacePhotos
{
    public function __construct(private PlacesClient $places) {}

    public function hero(string $placeId): ?string
    {
        $place = $this->places->details($placeId);

        if ($place === null || $place->photos === []) {
            return null;
        }

        return $this->places->photo($place->photos[0])->url();
    }
}

Facade method → client method

Every facade call maps one-to-one to the same method on PlacesClient:

MethodReturnsNotes
details(DetailsQuery|string)?PlaceOne place by id; null when Google answers 404.
autocomplete(AutocompleteQuery|string)Collection<AutocompletePrediction>Place predictions while the user types. Never cached.
session(?string $token = null)PlacesSessionAutocomplete billing session — autocomplete(), details(), token(), isFinished().
textSearch(TextSearchQuery|string)Collection<Place>Free-text search, one page.
nearbySearch(NearbySearchQuery)Collection<Place>Places within a radius of a point.
textSearchPaginated(TextSearchQuery|string)SearchPaginatorFollows nextPageToken for you.
nearbySearchPaginated(NearbySearchQuery)SearchPaginatorSame paginator shape over nearby search (single page).
findPlace(string, ?Location)?PlaceBest single match for a phrase, optionally biased.
geocode(ReverseGeocodingQuery|Location|float, ?float)Collection<ReverseGeocodingResult>Coordinates → addresses.
geocodeAddress(GeocodingQuery|string)Collection<ReverseGeocodingResult>Address → coordinates.
distance(DistanceQuery)Distance|MultipleDistancesDistance and travel time via the Routes API — one trip per destination.
matrix(array $origins, array $destinations)PendingMatrixFluent matrix builder — driving(), walking(), bicycling(), transit().
computeMatrix(MatrixQuery)DistanceMatrixFull origins × destinations matrix.
photo(string, int = 1600, int = 1600)PendingPhotoPhoto handle — url(), contents(), save().
photoUri(string, int = 1600, int = 1600)stringKey-free media URL, one request.
photoContents(string, int = 1600, int = 1600)stringRaw image bytes, one request.
photoUrl(string, int = 1600, int = 1600)stringKeyed media URL built locally, no request — server-side only.
check()list<ApiCheckResult>Is each Google API enabled and reachable with the configured key?
GooglePlaces::fake()GooglePlacesFakeFacade only — swap in the recording test fake.

Show your open-source love

This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.

More ways to support, including crypto

By donating, you agree to our donation terms.

Want this built into your product?

We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.