Filter Syntax Fundamentals
Theoper parameter accepts a structured JSON object with logical operators (and/or) and condition strings in the format:
Basic Example
Supported Operators
Comparison Operators
Comparison Operators
=— Equal!=— Not equal<— Less than>— Greater than<=— Less than or equal>=— Greater than or equal
Pattern Matching
Pattern Matching
like— Case-sensitive pattern (SQL LIKE)not like— Negated case-sensitive patternilike— Case-insensitive pattern (PostgreSQL ILIKE)not ilike— Negated case-insensitive pattern
The
% wildcard is automatically added if not present. Use explicit wildcards for prefix/suffix searches: name|like|Pro% or name|like|%EliteSet Operations
Set Operations
in— Value in setnot in— Value not in set
Range Operations
Range Operations
between— Value in range (inclusive)not between— Value outside range
Null Checks
Null Checks
null— Is NULLnot null— Is NOT NULL
No value is needed after
null or not null operators. The format is field|null.Date Operations
Date Operations
date— Matches date (ignores time)not date— Does not match date
Combining AND and OR Logic
Multiple AND Conditions
All conditions must be true:Multiple OR Conditions
At least one condition must be true:Mixed AND/OR Logic
Combine both operators for complex queries:Filtering by Relations
Filter the root dataset based on related records usingwhereHas.
Basic Relation Filter
Find products where the category name contains “electronics”:The relation key (
category) must be listed in Product::RELATIONS. The package validates all relation names for security.Nested Relation Filters
Filter by deeply nested relationships:Filtering vs. Eager Loading
Relation filters inoper affect which root records are returned:
- ✅ Returns products that have a matching category
- ❌ Does NOT load the category data
relations loads related data:
- ✅ Loads the category object for each product
- ❌ Does NOT filter the root dataset
- Filters products to those in electronics categories
- Eager-loads the category data for each result
Filtering Eager-Loaded Relations with _nested
By default, relation filters in oper only affect the root query via whereHas. Set _nested=true to also filter the eager-loaded relations.
_nested=true:
- ✅ Root query: returns products that have reviews with rating >= 4
- ✅ Eager-loaded reviews: only loads reviews with rating >= 4
_nested (default):
- ✅ Root query: returns products that have reviews with rating >= 4
- ✅ Eager-loaded reviews: loads all reviews for each product
Column Validation
Rest Generic Class validates all column names in filters to prevent SQL injection and typos.How It Works
- The package queries
information_schema.columnsto get valid column names - Results are cached for 1 hour (configurable)
- Invalid column names trigger a 400 error
Configuration
config/rest-generic-class.php
Example Error
Request:Disable column validation in development with
REST_VALIDATE_COLUMNS=false, but keep it enabled in production for security.Safety Limits
The package enforces limits to prevent query explosions that could overwhelm your database.Max Conditions
Default: 100 conditions per requestconfig/rest-generic-class.php
Max Depth
Default: 5 levels of nested relationsconfig/rest-generic-class.php
Real-World Examples
E-commerce: Find Discounted Products
Find active products with a discount, sorted by discount percentage:SaaS: Active Subscriptions Expiring Soon
Find subscriptions expiring in the next 30 days:CRM: High-Value Leads by Region
Find leads with high estimated value in specific regions:Troubleshooting
Filter Not Applied
Symptom: Results include records that should be filtered out Causes:- Typo in column name (check validation errors)
- Wrong operator (use
=not==) - Incorrect value type (use
truenot"true"for booleans)
- Enable
LOG_QUERY=trueto see generated SQL - Check logs at
storage/logs/rest-generic-class.log
Relation Filter Not Working
Symptom: Relation filter doesn’t affect results Causes:- Relation not listed in
MODEL::RELATIONS - Typo in relation name
- Wrong relation key (use method name, not table name)
- Verify relation exists:
php artisan tinker→Product::RELATIONS - Check error message for allowed relations list
Too Many Conditions Error
Symptom: 400 error “Maximum conditions exceeded” Cause: Query has more than 100 conditions Solution:- Split query into multiple requests
- Use
inoperator instead of multiple=conditions - Increase
max_conditionsin config (with caution)
Next Steps
Relation Loading
Learn how to efficiently load and filter nested relations
Hierarchical Data
Work with tree structures and parent-child relationships
API Reference
Complete operator reference and advanced filter patterns
Performance
Optimize query performance with caching strategies
Evidence
-
File:
src/Core/Services/BaseService.php
Lines: 1462-1539
ImplementsapplyOperTree,applyFilters, and relation filter extraction -
File:
src/Core/Traits/HasDynamicFilter.php
Lines: 13-252
Shows operator parsing, column validation, and filter application logic -
File:
config/rest-generic-class.php
Lines: 17-28
Defines safety limits (max_depth, max_conditions, allowed_operators) and validation settings