Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Google Api Bundle Laravel Package

endroid/google-api-bundle

Symfony bundle that integrates google/google-api-php-client into your app, letting you configure your application name and API key once and inject the ready-to-use client via the endroid.google_api_client service to access any Google API.

View on GitHub
Deep Wiki
Context7

Getting Started

Reality check before any install: this is a Symfony bundle, not a Laravel package. There is no service provider, no facade, no config publisher, and no package discovery. The README instructs you to register it in app/AppKernel.php via registerBundles() — that lifecycle does not exist in Laravel. If you composer require it in a Laravel app, nothing will happen at boot, and the endroid.google_api_client service it advertises will never be registered in your container.

The five-minute version for a Laravel developer: don't get started with this. Get started with the underlying library instead, which is what the bundle wraps (and which is also no longer named the same thing — see Gotchas).

composer require google/apiclient
// app/Providers/GoogleClientServiceProvider.php
public function register(): void
{
    $this->app->singleton(\Google\Client::class, function ($app) {
        $client = new \Google\Client();
        $client->setApplicationName(config('google.application_name'));
        $client->setDeveloperKey(config('google.api_key'));
        return $client;
    });
}
// config/google.php
return [
    'application_name' => env('GOOGLE_APPLICATION_NAME', config('app.name')),
    'api_key'          => env('GOOGLE_API_KEY'),
];

Where to look first if you inherited a Symfony app that actually uses this: the bundle's only moving piece is the DI registration of a single configured client. Open EndroidGoogleApiBundle/DependencyInjection/ and the service definition — that's 100% of what the package does. Read it once, translate it to the provider above, and you've reproduced the package.

First real use case in Laravel: pick the service class for the API you actually need and inject the client.

use Google\Service\Sheets;

class SheetReader
{
    public function __construct(private \Google\Client $client) {}

    public function read(string $spreadsheetId, string $range): array
    {
        $sheets = new Sheets($this->client);
        return $sheets->spreadsheets_values->get($spreadsheetId, $range)->getValues() ?? [];
    }
}

Note that the README's own example — Google_Service_Translate with listTranslations('Hello', 'fr') — targets the retired Translation API v2 and the legacy Google_Service_* class namespace. It will not run against a current google/apiclient install. Treat that snippet as documentation of the shape (client → service → call), not working code.

Implementation Patterns

The bundle's pattern, translated. The bundle's contract is: one shared client service, and you construct per-API service objects from it. In Laravel you express the same idea with a singleton binding plus thin, injectable wrapper classes per API. Keep the wrapper narrow — one method per Google call you actually make — so the boundary between your code and the SDK is a place you can swap the SDK later.

Auth pattern is where the bundle falls short, and it matters. The bundle only exposes application_name and api_key. An API key authenticates a narrow set of endpoints (public data lookups, some legacy APIs). It does not cover the things most teams actually want — Sheets, Drive, Calendar, Gmail, Cloud Storage — which require either OAuth2 user consent or a service account. The bundle's config schema has no surface for either. In Laravel, model all three paths explicitly rather than squeezing them through a "key":

// Service account (server-to-server: Sheets, Drive, GCS, Calendar on a shared calendar)
$client->setAuthConfig(storage_path('app/google/service-account.json'));
$client->addScope(\Google\Service\Sheets::SPREADSHEETS_READONLY);

// OAuth2 user consent — use Socialite to obtain the token, hand it to the client
$client->setAccessToken([
    'access_token'  => $user->google_access_token,
    'refresh_token' => decrypt($user->google_refresh_token),
    'expires_in'    => $user->google_token_expires_in,
]);

Config pattern. Don't commit a JSON key file. Read credentials from env or a secret store, cache config on deploy (php artisan config:cache), and keep one config/google.php for scalars plus a singleton binding for the client. If you need multiple Google identities (e.g., a service account for background jobs and a user token for interactive requests), bind them as named singletons rather than mutating one shared client — \Google\Client holds mutable state and will surprise you if two services share it mid-request.

Wrapper pattern for testability. Whatever you inject Google into should depend on your interface, not \Google\Client:

interface SpreadsheetReader {
    public function values(string $id, string $range): array;
}

Bind your implementation in a provider, and in tests bind a fake. Otherwise every test of a controller that touches Sheets makes a network call and needs a real service-account key.

Scheduling and observability pattern. Neither the bundle nor the raw client gives you retries, rate-limit backoff, or logging. Put those on your wrapper: retry on \Google\Service\Exception with 429/503 codes, log the API name and operation, and record token refresh failures distinctly from API errors. Doing this at the wrapper means you do it once.

Gotchas and Tips

The package name in the README is already stale. The bundle depends on google/google-api-php-client; the current package is google/apiclient. Old name, old class namespace (Google_Service_* vs Google\Service\*), old Guzzle constraints. Installing this bundle pins you to an intersection of two abandoned lineages — the wrapper and the SDK name it targets. If you find a composer.json in an inherited app constraining google/google-api-php-client, treat it as a separate upgrade task from the wrapper itself.

api_key will not authenticate the APIs you probably want. If your ticket says "read a Google Sheet" or "create a Calendar event," the bundle's config schema cannot express it. You need a service account or OAuth consent — plan for that before you promise a timeline based on "just install the bundle."

$this->get(...) doesn't exist on Laravel controllers. The README's usage is Symfony controller code. In Laravel use constructor injection or app(\Google\Client::class). Don't port the bundle's service-id string into Laravel expecting it to resolve.

Provenance is a flag, not a footnote. The repo link is abandroid/google-api-bundle; the README credits endroid. An archived personal fork of an abandoned bundle is a supply-chain shape worth verifying before you composer require it — check who publishes the Packagist entry and whether the source matches upstream. Even if it's a byte-identical mirror, the trust signal is negative.

Archived means frozen against PHP and Guzzle. No PHP 8+ compatibility work, no Guzzle major-version alignment, no CVE response. If it works on your current PHP, it will break on the next bump and nobody upstream will fix it. Pin the version if you must keep it at all, and treat pinning as a debt entry, not a config choice.

Debugging client issues. The failure modes are almost always: (a) auth method wrong for the API, (b) missing scope on an OAuth/service-account token, (c) expired access token without a refresh token to renew it, or (d) the API not enabled on the Google Cloud project. The SDK surfaces these as \Google\Service\Exception with a message and a getErrors()[0]['reason'] — log both. Turn on $client->setLogger($psrLogger) if you need request-level traces; without it you're guessing.

If you inherit a Symfony app running this: isolate it behind an interface, pin the version, add one smoke test that hits a real endpoint with a real credential (so you find out when Google changes something before your users do), and file a replacement ticket targeting your next planned upgrade. Do not fork it — MIT makes that legal, but a fork inherits the same PHP-8-and-Guzzle problem you were trying to escape.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons