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

Druid Bundle Laravel Package

thomask/druid-bundle

A Symfony bundle that integrates Apache Druid analytics into PHP applications. It registers Druid client services and configuration in the Symfony container, letting you run SQL and native Druid queries directly from your services with minimal setup.

View on GitHub
Deep Wiki
Context7

Getting Started

This is a Symfony 2/3 bundle, not a Laravel package — it ships no service providers, facades, or Laravel bindings. If you are in a Laravel codebase, treat it as reference code for the client class rather than something you composer require into a Laravel app.

For a Symfony app:

composer require thomask/druid-bundle

Register the bundle in app/AppKernel.php:

new Tmk\Bundle\DruidBundle\TmkDruidBundle(),

Configure in config.yml:

tmk_druid:
    host: localhost
    port: 8082           # broker
    indexer_host: localhost
    indexer_port: 8090   # overlord / indexer
    timeout: 30

First use case — pull the client service and run a native Druid JSON query:

$client = $this->get('tmk_druid.client');

$query = [
    'queryType'      => 'timeseries',
    'dataSource'     => 'wikipedia',
    'granularity'    => 'hour',
    'aggregations'   => [['type' => 'count', 'name' => 'rows']],
    'intervals'      => ['2014-01-01T00:00:00Z/2014-01-02T00:00:00Z'],
];

$rows = $client->query($query);

Read the bundle Client class in Client/Client.php first — that is the only file that matters day-to-day; everything else is DI wiring.

Implementation Patterns

Wrap the client, don't leak it into controllers. Druid's response shape is stable but unforgiving; wrap tmk_druid.client behind a DruidService so you can normalize responses, add retries, and (in Laravel) bind it from a service provider without touching callers.

Two distinct APIs, two distinct clients. The bundle exposes broker queries (/druid/v2/) separately from indexer operations (/druid/indexer/v1/ — create/kill datasources, enable/disable segments). Do not mix hosts: the broker port is 8082, the overlord is 8090. Getting these crossed yields 404s that look like Druid is down.

Prefer raw native JSON over partial builders. Druid evolves faster than this bundle; if the client exposes a query builder, treat it as a helper for the 3–4 query types you actually use (timeseries, topN, groupBy, select) and fall back to raw arrays for everything else (scan, timeBoundary, segmentMetadata).

Datasource lifecycle belongs in a command, not a controller. Creating or killing a datasource from a web request is a good way to take Druid down mid-request. Put createDataSource / deleteDataSource calls behind a Symfony Console command and require explicit confirmation.

Cache aggressively at the application layer. Druid is fast but every query is a fresh HTTP round-trip with no connection reuse. Wrap query() in a short-lived cache keyed by the serialized query payload (TTL 30–300s for dashboards).

Log the raw request and response. When a query fails, Druid's error is in the JSON body — not the HTTP status. Log the full request body before send and the full body on non-2xx.

Gotchas and Tips

  • Not a Laravel package. No ServiceProvider, no Facade, no config publishing. Symfony 2 bundle auto-registration only. In Laravel you'd copy Client/Client.php and its query classes into app/Services/Druid, replace any Symfony DI hints with constructor-injected Guzzle, and bind via a provider.
  • Unmaintained. Zero stars, zero dependents, no recent activity. Expect Guzzle 3/4-era code, PHP 5.4–7 signatures, and no Symfony 4+ Flex recipe. Do not plan long-term on this bundle — plan to replace with a small Guzzle client.
  • Errors are HTTP 500 with JSON bodies. Druid returns {"error": "..."} for query syntax mistakes, bad intervals, and missing datasources alike. The bundle may surface these as generic exceptions; check the body, not the exception message.
  • Empty results are [], not null. Guard against current($rows) returning false and against count($rows) === 0 when rendering — a zero-row timeseries is not an error.
  • Times timestamps are ISO-8601 strings, not Unix ints. If you aggregate in PHP, parse with DateTimeImmutable and be explicit about UTC — Druid returns "2014-01-01T00:00:00.000Z" regardless of your app timezone.
  • Timeout defaults are not sane for large intervals. Set timeout explicitly in config; a groupBy over 30 days can easily exceed 30s and the HTTP client will drop the response while Druid keeps computing.
  • Extension points are thin. There is no pluggable HTTP transport in the public API; if you need retries, circuit-breaking, or auth, wrap the client — do not subclass it.
  • Druid versions diverge. This bundle predates Druid 0.10+ query features (resultFormat, context, SQL endpoint). If your Druid is newer than ~0.9, assume the bundle knows none of the modern options and pass them through raw arrays.
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.
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle
adachsoft/api-version-bundle
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
cgv/localized-resource