solution/pipeline-builder
A Laravel package for composing reusable, testable pipelines from modular stages, with a fluent builder API for defining, running, and managing multi-step data processing workflows in PHP applications.
Architecture fit. solution/pipeline-builder is a client-side fluent DSL that emits MongoDB aggregation pipeline documents (arrays of stage BSON). It occupies the "query construction ergonomics" layer — it sits between application/domain code and the mongodb/mongodb driver, and it does not touch connection management, pooling, or schema concerns. That is a narrow, low-blast-radius position in a Laravel stack: it produces an array, and the array is what actually runs. That shape is favorable for incremental adoption because the dependency can be isolated behind a single interface and swapped later.
The fit question is really whether a DSL is needed at all. Laravel's dominant Mongo integrations (mongodb/laravel-mongodb) expose aggregate() on the query builder and Model::raw(), so raw pipelines are already expressible. What the ecosystem lacks is a fluent, testable, composable pipeline builder — particularly for conditional pipeline fragments, $facet sub-pipelines, and reusable stage chunks. If the team's pain is "pipelines are long literal arrays that are hard to compose and diff," this package addresses a real gap. If the pain is "we don't understand aggregation semantics," this package does not help and adds a dependency.
Integration feasibility. Mechanically trivial to install (Composer, PSR-4), but the feasibility assessment is dominated by three blockers:
| Factor | Finding | Severity |
|---|---|---|
| License | GPL-2.0 — strong copyleft. Laravel ecosystem norm is MIT. Distribution or SaaS linkage may trigger source obligations; enterprise OSPOs typically reject GPL-2.0 in a vendored app tree without legal sign-off. | High |
| Currency | Last release 2016-04-20. Predates PHP 7.1, PHP 8, and the mongodb driver's modern era. Curly-brace string offsets, each(), create_function, and untyped legacy array syntax are plausible PHP 8 hard failures. |
High |
| Lineage | Unclear whether it targets the removed legacy mongo extension / abandoned doctrine/mongodb or the modern ext-mongodb + mongodb/mongodb. If the former, it is unusable without a rewrite, not a patch. |
High |
| Validation | 5 stars, 0 dependents, no downstream consumers. There is no field evidence it works at scale, no issue history to mine, and no CVE feed. | Medium |
Technical risk. The dominant risk is not runtime instability — it is silent semantic incorrectness. A hand-rolled DSL that emits a structurally valid but semantically wrong pipeline (stage ordering, $project inclusion/exclusion mixing, BSON type coercion between PHP int/float and Mongo Int32/Int64/Double, DateTime → UTCDateTime conversion) returns wrong data with a 200 OK. That class of failure is expensive to detect and erodes trust in the data layer. Secondary risks: GPL contamination of the product's distribution model, and Composer conflict churn against illuminate/* and mongodb/mongodb version constraints during framework upgrades.
Key questions.
mongo/doctrine/mongodb, or ext-mongodb + mongodb/mongodb? This single answer determines whether the evaluation continues.composer require and a smoke test under our current PHP (8.2/8.3) and driver major version without patching?$match, $group, $project, $unwind, $lookup, $facet, $graphLookup, $setWindowFields, $merge? Modern pipelines rely on stages that did not exist in 2016.Stack fit. In a Laravel + MongoDB service, the natural integration point is a thin adapter: define a PipelineFactory/AggregationCompiler interface in domain terms, implement it with this package, and keep all call sites typed against the interface. That caps the exit cost at one class if we abandon the dependency. Do not let Solution\PipelineBuilder\* types leak into controllers, jobs, or repositories.
Buy-vs-build-vs-fork. Three credible paths, in order of preference:
mongodb/mongodb's Builder is a modest, well-bounded piece of work. It is MIT-clean, PHP 8-native, testable against a golden-file corpus of pipeline arrays, and requires no external negotiation. Given the package's 10-year dormancy and copyleft license, the TCO comparison is not close.doctrine/mongodb-odm's Aggregation\Builder if ODM is already in the stack — it is maintained, MIT, and covers stage builders well.Compatibility. Before any code is written, run a 1-hour gate: clone, composer install on our PHP version, execute one representative pipeline against a scratch mongod at our target server version, diff the emitted document against the equivalent hand-written pipeline. If it fails the gate, the evaluation ends — no exceptions, no "we'll patch it."
Sequencing.
$lookup, $facet, $merge, window functions).explain() plan shape in integration tests, enforce allowDiskUse and maxTimeMS at the adapter boundary.$out/$merge side effects until the read path is proven.Maintenance. Taking this dependency means inheriting it. Upstream has been dormant since April 2016 — there is effectively no maintainer, no release cadence, and no expectation of a response. Ownership transfers to us: PHP and driver upgrade work becomes our backlog item, not a version bump. Ongoing cost is modest in absolute terms (a small, stable surface) but it is unbudgeted recurring cost that never expires, and it lands on whoever next touches the framework upgrade. Rough planning figure: 0.1–0.2 FTE amortized, spiking sharply at each PHP and MongoDB server major.
Support. None. No maintainer, no issue triage, no security advisory channel. It must go on the SBOM with a manual review cadence and a documented "abandoned, internally owned" annotation — otherwise it silently rots until a compliance audit surfaces it, which is a worse outcome than a small annual review.
Scaling. Negligible runtime overhead — it is array construction, microseconds per query, no connection or memory footprint. The scaling risk is entirely in what it lets you build. A fluent DSL lowers the activation energy for expensive pipelines: an unguarded $lookup across an unindexed foreign collection, or a $group that blows the 100 MB in-memory limit, is a few fluent calls away. Enforce guardrails at the adapter boundary rather than trusting call sites: maxTimeMS, allowDiskUse, batch size, and a hard rule that $match precedes $lookup in generated output. Add CI checks that assert an index-backed plan via explain() for any new pipeline in a hot path.
Failure modes.
| Mode | Symptom | Mitigation |
|---|---|---|
| Semantic mis-compilation | Correct-looking results, wrong numbers, no error | Golden-file tests diffing emitted stage arrays; fixture-based integration tests |
| BSON type coercion | $match misses documents; numeric comparisons off |
Explicit casts at adapter; test with Int64 and Decimal128 fixtures |
| Stage ordering | Full collection scan, p95 latency regression | Lint rule on emitted stage sequence; explain() assertions in CI |
| PHP/driver incompatibility | Fatal error at autoload or on first pipeline | The compatibility gate; pin PHP and driver majors in CI |
| Abandonment | No patch for a future breaking change | Interface isolation + fork-ownership ADR |
| License exposure | Distribution/SaaS review finding | Legal gate before adoption, not after |
Ramp-up. The API surface is small and idiomatic; an engineer productive in Laravel's query builder will be productive here in under a day. The trap is assuming the builder teaches MongoDB: it does not. The team still needs real aggregation-framework fluency — stage semantics, index-aware ordering, memory limits — because the builder will happily compile a pipeline that is legally valid and operationally terrible. Budget the ramp-up on MongoDB, not on this package.
Bottom line. This is a reference implementation, not a dependency. At 5 stars, 0 dependents, a 2016 last release, and a GPL-2.0 license, the risk-adjusted case for adoption is weak; the risk-adjusted case for reading its API and building a ~500–1000 LOC MIT-licensed internal equivalent behind an interface is strong. Revisit only if the author confirms driver lineage, relicensing willingness, and willingness to resume maintenance.
How can I help you explore Laravel packages today?