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

Serializer Expression Laravel Package

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.

View on GitHub
Deep Wiki
Context7

Getting Started

jlm/serializer-expression is a small add-on for JMS Serializer that lets you decide at runtime whether a property should be excluded, using a Symfony Expression Language expression instead of static groups/versions. It is archived and unmaintained (2 stars, 0 dependents), so treat it as a reference implementation or vendored helper rather than a long-term dependency.

Minimal steps:

  1. Verify compatibility before installing. The package predates modern Symfony; its symfony/expression-language constraint is likely pinned to an old major. Run:
    composer require jlm/serializer-expression --dry-run
    composer why-not symfony/expression-language
    
    If constraints conflict (common on Symfony 5+/PHP 8), fork the repo, bump constraints, and require your fork via a VCS repository.
  2. Confirm the wiring style. Read the README and src/ first — the package exposes either an exclusion strategy you register on SerializerBuilder or an annotation you enable via a metadata driver. Everything else follows from which of those it is.
  3. First use case: hide sensitive/role-gated fields on an existing entity without touching serialization groups:
    // Goal: never serialize $salary unless the viewer is an admin.
    $context = SerializationContext::create()->setAttribute('is_admin', $currentUser->isAdmin());
    $json = $serializer->serialize($employee, 'json', $context);
    

Implementation Patterns

Strategy registration (builder-based). If the package ships a strategy class, register it where you build the serializer:

$serializer = SerializerBuilder::create()
    ->addExclusionStrategy(new ExpressionExclusionStrategy($expressionLanguage))
    ->build();

In Laravel, do this once inside a service provider and bind the configured serializer as a singleton — don't rebuild it per request.

Annotation/metadata-based. If it uses annotations, attach the expression to the property alongside existing JMS metadata:

/** @Serializer\Exclude(if="!is_admin") */
private $salary;

Keep the expression focused on one object and context variables; long expressions become untestable.

Pass state through the serialization context, not globals. The cleanest pattern is to feed the decision inputs as context attributes and reference them in expressions (is_admin, viewer_id, include_internal). This keeps controllers in control and makes the strategy stateless and testable.

Compose with groups. Use groups for coarse "which shape" decisions and this package only for the handful of fields that depend on runtime state (ownership, feature flags, tenancy). Order matters: exclusion strategies run per property, so an expression can only remove fields a group already allowed — it can't add them back.

Wrap it behind your own service. Expose something like ReportSerializer::forViewer($user) that builds the context and calls JMS Serializer. That isolates the archived dependency to one class and makes swapping to JMS's built-in Expression strategy a one-file change later.

Testing pattern. Assert absence, not just presence:

$this->assertArrayNotHasKey('salary', json_decode($json, true));

Gotchas and Tips

  • The package is archived. No bug fixes, no PHP 8/Symfony 6 support guaranteed. Before adopting, check whether JMS Serializer's built-in Expression exclusion strategy already covers your need — it likely does, and it's maintained. This package is best treated as prior art.
  • Dependency deadlock. Old symfony/expression-language pins are the most common install failure. Prefer forking with widened constraints over --ignore-platform-reqs hacks that break at runtime.
  • Missing context variables throw. Referencing an attribute you didn't set raises an expression syntax/evaluation error surfaced as a serialization failure. Use null-safe operators (is_admin is defined and is_admin) or always seed defaults.
  • Applies to both directions. Exclusion strategies run on deserialization too — an expression that hides salary from output can also block it from being hydrated on input. Verify request parsing separately.
  • Doctrine proxies. Property access on lazy proxies can trigger loads or miss private state. Reference getters (object.isAdmin()) rather than raw properties where possible.
  • Performance. Expressions are evaluated per property per object. For large collections, compile expressions once and avoid heavy method calls inside them; profile before putting this in a hot export path.
  • Errors are opaque. Expression failures bubble up as generic serializer exceptions. Wrap serialization in a try/catch during development and log the expression + context to debug quickly.
  • Extension point. If the package exposes its ExpressionLanguage instance, register custom functions via a ExpressionFunctionProviderInterface rather than embedding complex logic in annotation strings.
  • Security. Expressions are developer-authored config — never interpolate user input into them. Context values are fine; context expression strings are not.
  • Migration plan. Because of the archive status and 0 dependents, keep the surface area small (one wrapper service, one strategy registration) so migrating to native JMS Expression or a custom ExclusionStrategy is trivial.
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.
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle