⚙️ Expression Engine
The Expression Engine is a flexible and expressive filtering engine designed to handle both flat and deeply nested filters, including relationships and their attributes.
It is ideal when you want the power of RuleSet-style syntax but also need to filter through relationships and nested relations easily.
📦 Example Request
GET /posts?filter[status]=pending&filter[author.profile.name][like]=kettasoft
This will:
- Filter posts where
status
ispending
- AND where the related author's profile
name
containskettasoft
🛠️ How It Works
Filters are parsed from the request's
filter
key.Each filter can be a:
- Simple key-value pair (e.g.,
filter[status]=active
) - Operator-based pair (e.g.,
filter[name][like]=kettasoft
) - Nested relation filter (e.g.,
filter[author.profile.name]=ahmed
)
- Simple key-value pair (e.g.,
The engine determines the filter structure and applies the corresponding query constraints.
🔧 Default Operator
If a filter doesn't specify an operator, the default operator will be used.
This default is configurable in the engine settings.
'default_operator' => '='
✅ Supported Features
- ✅ Flat and nested filters
- ✅ Dot notation for relationships (e.g.,
author.profile.name
) - ✅ Customizable default operator
- ✅ Whitelisting of allowed fields & relations
- ✅ Works well with eager loading and relationship validation
- ✅ Prevents filtering on undefined fields (optional strict mode)
✅ Allowed Fields & Relations
To avoid unauthorized or unintended access, you can configure the engine to only accept specific fields or relations:
Filterable::create()->useEngine('expression')
->allowdFields(['status'])
->allowRelations([
'author.profile' => ['name'] // specific fields in this relation
])->paginate()
In strict mode, unsupported fields will be rejected with a validation error.
📌 Use Case
Post::filter($filters, ExpressionEngine::class)->get();
🧠 Internal Logic (Simplified)
- Parse the
filter
array recursively. - Detect relationships via dot notation.
- Resolve the relation path and apply
whereHas
queries for related models. - Build appropriate SQL queries via the Eloquent builder.
- Use the defined or default operator.