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

Eloquent Serialize Laravel Package

anourvalar/eloquent-serialize

Serialize and restore Eloquent query builders with ease. Capture chained queries including eager loading, where clauses, and limits, then unserialize later to run them. Supports Laravel 6 through 12.

View on GitHub
Deep Wiki
Context7

Product Decisions This Supports

The real decision this package forces is not "should we add a dependency" — it's "do we persist a query, or persist the inputs to a query?" Almost every team eventually needs one of these features and quietly grows a bespoke serializer in app/Support/ to do it. Nobody signs off on that; it just becomes a permanent maintenance tax. This package makes the cheaper branch of that fork priceable in an afternoon, so the tradeoff gets made on purpose instead of by drift.

Concretely, it supports:

  • Deferred execution of existing queries. "Run export," "email me this report," "refresh this dashboard nightly" — features where the selection logic already exists as a chained Eloquent call and only needs to move from the request cycle into a queue worker. This is the highest-value, lowest-risk entry point and it ships in days, not a quarter.
  • Saved views / saved filters. Users define a filter set once and re-run it later. Note carefully: the package gives you the mechanism, not the feature. The durable part of "saved views" is the versioning, schema-drift detection, tenant pinning and validation envelope you'd have to build either way. Budget for that; don't let a demo of serialize/unserialize create the impression the feature is nearly done.
  • Cross-boundary query handoff. One service or job builds the query where the domain context lives; another executes it where the compute belongs. Useful for report runners, backfill tooling and internal admin ops.
  • Roadmap sequencing — the cheap spike. If "background exports" or "saved reports" is a candidate for next quarter, this is a one-sprint, one-engineer validation with a one-file exit ramp. It buys real information for the DTO-vs-serialized-builder decision before you commit architecture to either.
  • Pricing the build-vs-buy honestly. The alternative isn't free — it's a DTO plus a toQuery() mapping plus tests, maintained forever. Having both approaches on the table for a single sprint is what makes the choice defensible in a review, rather than a matter of taste.

What it explicitly does not buy you: performance. It caches the builder, not the rows — the database still executes on deserialize. If the business goal is fewer round trips or faster pages, this is the wrong tool and Cache::remember is the right one. Being clear about this up front prevents a "we adopted a serialization library and dashboards didn't get faster" credibility hit.

When to Consider This Package

Adopt when most of these hold:

  • Laravel 6–12 shop (it spans all of them, so an upgrade in flight isn't a blocker).
  • Payloads are internal only — created by your code, stored in rows your app writes, never echoed to a client, never accepted from a user.
  • The query shapes are known and few — exports, reports, a handful of saved filters. Each shape can be covered by a round-trip test.
  • Payloads are short-lived or explicitly frozen — a queued job that runs in minutes is ideal; a saved report executed for years is not, without extra work.
  • You're willing to own a thin wrapper (QueryPayload::from() / toBuilder()) and treat the package as a primitive rather than an API your controllers call.
  • You can pin the version and upgrade through CI, not straight to prod.

Look elsewhere — specifically, use the DTO pattern — when any of these are true:

  • Users author the query. A payload names a model class, so a forged one can point at any model in the app. If a user needs to control what runs, they author a DTO; they don't author a payload. This is a hard line, not a preference.
  • Moving date values are central. A serialized now()->subDays(30) is frozen at serialize time — a daily report saved on day 1 still means "the 30 days before day 1" on day 7. If the query means "last 30 days," the values must be bound at execution time, which means you need a parameterised DTO anyway.
  • Long-lived saved views with an evolving schema. A column rename six months after you persisted thousands of payloads is the failure that actually hurts. You can mitigate with a schema hash, but you're building the DTO's tolerance by hand.
  • Closures or constrained eager loads are load-bearing. Closures don't survive; a dropped where returns wrong rows silently, and a dropped eager-load constraint becomes an N+1 in the worker. Testable, but a standing cost.
  • You need raw SQL, DB::table(), transactions, lockForUpdate(), or pagination state beyond limit/offset. Out of scope by design.
  • Payloads are large. A 10k-element whereIn becomes 10k bindings and can blow an SQS 256 KB limit or a queue driver swap. Solvable by storing the payload and passing a row ID — but that's now your design, not the package's.
  • You need a vendor, an SLA, or procurement sign-off on continuity. Single maintainer, ~117 stars, zero dependents. That is a contained dependency, not a platform bet.

Decision gate worth writing down before the spike: if the round-trip test suite needs more than a handful of custom cases to be trustworthy, or if the payload must outlive a schema change, stop and build the DTO. Both outcomes are cheap to reach from here.

How to Pitch It (Stakeholders)

To executives — one paragraph: For the cost of a small MIT-licensed dependency and roughly one engineer-sprint, we can validate whether "background exports" and "saved reports" are worth building next quarter, without committing architecture. It's a decision-making tool first and a feature enabler second. The dependency is low-profile (single maintainer, small user base), so we contain it behind an internal wrapper — if it's abandoned or we outgrow it, the exit is one file, not a refactor. Risk is time-boxed and reversible; the information we get is not.

To engineering — the framing that matters: Treat this as a serialization primitive, not a framework. Wrap it immediately; the wrapper is where the payload envelope, versioning, schema hash, tenant/connection pinning and logging live — none of which the package provides. The README is three examples, so our test suite is the spec: round-trip every query shape we actually use and assert toSql(), getBindings() and eager-load keys, not just that it "works." Expect to call ->on($connection) explicitly after deserialize, expect closures to be dropped, expect global-scope behaviour to drift and be worth testing, and check the wire format before any payload leaves the process — a:/O: means PHP serialize(), which is an object-injection primitive if the string is ever attacker-influenced. It ships no telemetry, so our serialize/unserialize diff log is the only signal when a "working" query starts returning the wrong set.

What we should not claim: that this makes anything faster, that it's a security boundary, or that it gives users a query language. It defers and transports queries our code wrote. Marketing it as more than that is how a one-file dependency becomes a nine-month platform project.

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.
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core