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

Cloud Bigquery Connection Laravel Package

google/cloud-bigquery-connection

Official Google Cloud PHP client for BigQuery Connection. Install with composer require google/cloud-bigquery-connection, authenticate with Google Cloud credentials, then use ConnectionServiceClient to manage and retrieve BigQuery connection resources over REST or gRPC.

View on GitHub
Deep Wiki
Context7

Getting Started

1. Install

composer require google/cloud-bigquery-connection

Optional but recommended for lower latency:

pecl install grpc && composer require google/protobuf

The client auto-selects gRPC when ext-grpc is loaded and silently falls back to REST otherwise — no code changes needed.

2. Authenticate

Use Application Default Credentials (GOOGLE_APPLICATION_CREDENTIALS=/path/to/sa.json or workload identity). Don't commit JSON keys; put them in .env/Secret Manager and reference a path:

// config/services.php
'bigquery_connection' => [
    'project'  => env('GOOGLE_CLOUD_PROJECT'),
    'location' => env('BIGQUERY_CONNECTION_LOCATION', 'US'),
],

Note the credentials client option is deprecated as of v2.1.0 — pass a path via GOOGLE_APPLICATION_CREDENTIALS, or inject a Google\Auth\Credentials\ServiceAccountCredentials object through credentialsCallback/requestHandler if you truly need runtime secrets.

3. Look here first

  • Google\Cloud\BigQuery\Connection\V1\Client\ConnectionServiceClient — the only class you normally touch (the older ConnectionServiceGapicClient and the legacy V1 surface are deprecated since 1.5.0).
  • Google\Cloud\BigQuery\Connection\V1\Connection — the resource DTO you'll serialize/hydrate.
  • Static name helpers: ConnectionServiceClient::connectionName($project, $location, $connection), ::locationName(), ::projectName().

4. First use case — audit existing connections

The fastest sanity check and a genuinely useful Artisan command:

use Google\Cloud\BigQuery\Connection\V1\Client\ConnectionServiceClient;
use Google\Cloud\BigQuery\Connection\V1\ListConnectionsRequest;

$client = new ConnectionServiceClient();
$request = (new ListConnectionsRequest())
    ->setParent(ConnectionServiceClient::locationName(config('services.bigquery_connection.project'), 'US'));

foreach ($client->listConnections($request)->iterateAllElements() as $connection) {
    $this->line($connection->getName().' -> '.$connection->getFriendlyName());
}

If that prints your connections, auth, region, and networking are all correct.

Scope reminder: this package manages connection resources (Cloud SQL, Spanner, BigLake, Spark, Salesforce). It does not run queries. Querying lives in google/cloud-bigquery.

Implementation Patterns

Bind the client as a singleton. Creating a client builds a gRPC channel / Guzzle handler — expensive per request.

// app/Providers/BigQueryConnectionServiceProvider.php
$this->app->singleton(ConnectionServiceClient::class, fn () => new ConnectionServiceClient([
    'transport' => config('services.bigquery_connection.transport', 'grpc'),
]));

$this->app->singleton(BigQueryConnectionManager::class, fn ($app) => new BigQueryConnectionManager(
    $app->make(ConnectionServiceClient::class),
    config('services.bigquery_connection.project'),
    config('services.bigquery_connection.location'),
));

Wrap it in a domain service. Keep protobuf out of controllers; return arrays/DTOs so your app stays testable.

class BigQueryConnectionManager
{
    public function __construct(
        private ConnectionServiceClient $client,
        private string $project,
        private string $location,
    ) {}

    public function get(string $id): array
    {
        $name = ConnectionServiceClient::connectionName($this->project, $this->location, $id);

        return json_decode(
            $this->client->getConnection(new GetConnectionRequest(['name' => $name]))->serializeToJsonString(),
            true
        );
    }
}

Provision connections from a job, not a request. Creating a Cloud SQL connection blocks on Google-side validation (up to ~30s). Dispatch a queued job that creates the connection, then writes the connection id back to your tenant/integrationsettings model.

$connection = $client->createConnection(
    (new CreateConnectionRequest())
        ->setParent(ConnectionServiceClient::locationName($this->project, $this->location))
        ->setConnectionId("tenant-{$tenant->id}")
        ->setConnection((new Connection())
            ->setFriendlyName("tenant-{$tenant->id}")
            ->setCloudSql((new CloudSqlProperties())
                ->setInstanceId('my-project:us-central1:my-db')
                ->setDatabase('app')
                ->setType(CloudSqlProperties\DatabaseType::POSTGRES)
                ->setCredential((new CloudSqlCredential())->setUsername('bq')->setPassword($secret))))
);

Store the connection's friendly name, not the full resource path. Federated queries reference the friendly/connection id (EXTERNAL_QUERY("my-project.US.tenant-42", ...)), and it's what other teams will ask for.

Credential rotation is an update with a field mask. This is the most common day-to-day operation:

$client->updateConnection(
    (new UpdateConnectionRequest())
        ->setConnection((new Connection())
            ->setName(ConnectionServiceClient::connectionName($this->project, $this->location, $id))
            ->setCloudSql((new CloudSqlProperties())
                ->setCredential((new CloudSqlCredential())
                    ->setUsername($user)->setPassword($newPassword))))
        ->setUpdateMask((new FieldMask())->setPaths(['cloud_sql.credential.password']))
);

Preflight permissions. Before letting a user attempt creation in a UI, call testIamPermissions with bigquery.connections.create to render a clean 403 instead of a stack trace.

Cache the connection list. listConnections has no server-side filter and eats your BigQuery Connection API quota. Cache per project/location for a few minutes with Cache::remember(), keyed so a create/delete in your app busts it.

Paginate deliberately. listConnections() returns a PagedResponse; use iterateAllElements() for commands/jobs and getPage() inside HTTP endpoints so you can expose a page token to the frontend and avoid unbounded loops.

Testing. Never hit the network in CI. Bind a ConnectionServiceClient configured with a MockHttpHandler/mock transport, or (simpler) type-hint your own BigQueryConnectionManager interface and fake it. Assertions on $connection->serializeToJsonString() are readable and stable.

Gotchas and Tips

  • Location is not a project default. US, EU, and specific regions are distinct parents — a connection created in US is invisible to a EU list call. Make location an explicit config value, and expect NOT_FOUND when someone forgets it.
  • The API is not the query API. EXTERNAL_QUERY execution, datasets, and jobs all live in google/cloud-bigquery. Reaching for this package to run SQL is the #1 wrong turn.
  • updateConnection without an updateMask silently does nothing useful. Only display_name, description, and cloud_sql.credential.* are mutable; attempting to change instance_id/database requires delete + recreate. Build the mask from the fields you actually changed rather than hardcoding.
  • Don't mutate a returned protobuf and re-send it. Connection objects are mutable; if you tweak one for output and later reuse it, you'll send stale/leaky fields. clone before modifying, and prefer sending a freshly built message.
  • setIamPolicy is a full replace. Read the current policy with getIamPolicy, append your binding, and use the returned etag — omitting it causes ABORTED on concurrent edits. Additive IAM is not a thing here.
  • Deleting a connection still referenced by a view or scheduled query fails. Catch ApiException with FAILED_PRECONDITION and surface "in use" rather than a 500.
  • Retry configuration is per-call, not per-client magic. For create/testIamPermissions, either rely on GAX's default retry idempotency or wrap in Laravel's Retry::times(3)->exponential() — but never retry createConnection blindly without a deterministic connection_id, or you'll get ALREADY_EXISTS.
  • ApiException is your only failure type. Map getStatus(): PERMISSION_DENIED / UNAUTHENTICATED → config or auth problem; NOT_FOUND → wrong project/location/name; INVALID_ARGUMENT → usually a missing or malformed field-mask path. Log $e->getStatus() and $e->getDetails(), not the whole credential-bearing message.
  • Never log with print_r($connection). Use serializeToJsonString() after stripping, and keep Cloud SQL passwords out of logs and out of your toArray() DTOs entirely.
  • gRPC extension missing is not an error. The client degrades to REST, which is fine for CRUD but noticeably slower for batched list calls. Force ['transport' => 'rest'] explicitly if you want deterministic behavior between local and prod.
  • Universe domain support landed in 1.5.0 (serviceAddress templates). If you use a non-default universe or a VPC-SC perimeter, set the endpoint template in config rather than editing generated code.
  • Version skew matters: v2.0.0 was a breaking surface change, and 2.0.2 added PHP 8.4 compatibility. Pin ^2.2 and let Dependabot do its thing; don't mix v1 and v2 examples from the docs.
  • Extension point to remember: because this is a GAPIC client, ['defaultCallOptions' => ['timeoutMillis' => 60000]], custom retrySettings, and logger (documented in 2.0.2) can all be passed in the constructor array — that's usually a better lever than wrapping every call.
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.
adachsoft/changelog-linter
adachsoft/collection
payerurl/telegrambot-crypto-payment-instant-payout
dskripchenko/laravel-hybrid-search
riorizkyrainey/lara-ced
mehedimi/static-vel
zharp/zharp
nonsapiens/bigquery-model-sync
lgu-bayambang-ict-office/lgu-laravel-development-standards
andydefer/laravel-support
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus
elmogy/larafast