jlm/serializer-expression
Expression-driven serializer for PHP and Laravel: define how models and objects map to arrays using expressive rules, keeping API output, transformations, and serialization logic clean, reusable, and easy to maintain.
@Exclude(if="...")) rather than hardcoding per-endpoint DTOs — is a real architectural fork in the road. It informs whether your team standardizes on declarative, annotation-driven payload shaping or explicit resource classes (Laravel API Resources, Fractal transformers).analytics_summary, Free users don't" and "support agents see last_login_ip, customers don't" — a repeated product ask that otherwise turns into a proliferation of near-duplicate serializers.Consider studying it (not installing it) when:
jlm/serializer or JMS Serializer and need to understand the pattern before reimplementing it.Look elsewhere — in practice, always — when:
Preferred alternatives: Laravel's native JsonResource conditionals (when(), whenHas(), whenNotNull()) for most cases; $hidden/$visible plus selective makeHidden() for coarse control; spatie/laravel-fractal or league/fractal if you want transformer-level includes; and a ~150-line internal VisibleWhen policy class wrapping symfony/expression-language if you genuinely need declarative predicates. If you are already on jms/serializer, use its built-in expression-based exclusion rather than adding a second layer.
To executives — one paragraph: We evaluated a package that solves a real and recurring product problem: hiding fields in API responses at runtime based on who is asking, instead of maintaining separate response classes per role or plan. The capability is worth having — it directly supports data-minimization commitments, enterprise security reviews, and plan-based feature gating in payloads. The package is not viable: it is archived, has two stars and zero known dependents, and would put unmaintained code on the path that protects customer data. Recommendation: fund a small internal capability (roughly 2–5 engineer-days) modeled on the same idea, with tests and an owner. Expected payoff is reduced duplication in our API layer and a defensible answer in security questionnaires. Risk of the alternative — adopting it — is an unpatched component in a PII-adjacent code path with no one to call.
To engineering — the ask: Don't add jlm/serializer-expression to composer.json. Two options: (1) if our needs are simple, use Laravel JsonResource::when() conditionals and a policy call — ship this week, no new dependency; (2) if we truly need declarative predicates in field metadata, build a thin symfony/expression-language wrapper with a whitelisted variable context (user, tenant, plan, flags), fail-closed on expression errors, and 100% test coverage on the exclusion path. Treat the archived package as design input only. Two non-negotiables for option 2: expressions must never be able to reach the container or the database (no arbitrary method calls on user objects), and an exclusion failure must return fewer fields, never more.
Framing to avoid: don't present this as "we found a package and rejected it." Present it as "we validated the pattern, rejected the artifact, and are proposing a smaller, owned implementation" — that is a stronger story and it keeps the roadmap decision (declarative payload shaping, yes/no) visible rather than buried in a dependency review.
How can I help you explore Laravel packages today?