betalabs/engine-api-handler
Laravel package that simplifies integration with Betalabs Engine APIs by providing reusable request handlers, standardized JSON responses, and consistent error handling, reducing boilerplate so you can focus on building your application.
This release (v5.0.2) is the 5.x line of the index/listing handler that sits on top of betalabs/laravel-api-handler. Treat the requirements as hard gates before you touch code:
^8.2 (built and tested against 8.5), Laravel 10–12 (target 12), and betalabs/laravel-api-handler ^5.0.First steps:
composer require the package and confirm composer why betalabs/laravel-api-handler resolves to ^5.0 — a stale lock entry is the most common install failure here.AbstractIndexHandler; each of your resource listings typically extends it and declares the allowed filters, sortable fields, joins and eager loads.Base-Model-Total header (emitted by ModelCountMetaProvider). Both are covered by the new test suite, so behaviour should be stable, but confirm your client reads the header casing exactly.First realistic use case: take one listing endpoint (ideally one with a conditional join, e.g. a tenant-scoped join) and port it. That exercises Filter, Sort, Field, Join, With and the count provider in one go, which is exactly the surface the new tests cover.
Declare capabilities, let the handler parse. AbstractIndexHandler turns query string into Filter, Sort, Field, Join and With objects. Keep the parsers declarative (which fields are filterable/sortable, which relations are joinable/eager-loadable) and resist writing per-endpoint conditionals — the parsers are the extension point.
Filter approaches. Per-field filtering supports an OR approach (_filter-approach=or) and multi-column syntax (a|b) as well as multi-value (title=A|B). In 5.0.2 both of these actually filter now — previously OR with multiple values silently dropped the values, and campo-not=null produced IS NULL, i.e. the inverse of what was asked. Write integration tests against these shapes rather than trusting the query string.
Sorting across joins. Sort now applies the join table alias for polymorphic joins, matching what Filter and Field already did. If you previously worked around this with raw orderByRaw or a custom sort parser, remove the workaround — keeping it will now double-qualify the column.
Joins and relations. Join supports BelongsTo (fixed to use getOwnerKeyName()) and MorphToMany. Prefer With for eager loading and Join only when you genuinely need to filter or sort on the joined table; joining what you could eager load is the usual cause of duplicate rows and inflated counts.
Count metadata. ModelCountMetaProvider backs the Base-Model-Total header. In 5.0.2 it clears JOIN and ORDER BY bindings before counting (fixing MySQL HY093 on listings with conditional joins) and returns null instead of throwing when handed a relation rather than a builder. Passing the builder is still the correct usage — the null return is a guard, not a supported mode.
Integration tips. Keep the handler thin and put domain scoping in the builder/query you hand it. Register the service provider and any config publish in the usual Laravel way, then run the package's own suite once locally (vendor/bin/phpunit in the package, or its documented command) to confirm your PHP/Laravel combination is green before debugging your own code.
campo-not=null now filter correctly. Any listing that depended on the broken behaviour will return fewer rows after upgrade. Audit dashboards and reports that use _filter-approach=or or -not=null before deploying.array_except, array_forget, array_first, str_random, starts_with with Arr::/Str::. You no longer need laravel/helpers because of this library — but if your app code still calls those helpers, keep the dependency or migrate your own calls.Input facade is gone. Replaced with Request::all(). Grep your overrides and custom parsers for Input:: — it was removed in Laravel 11 and will fatal on 11/12.nesbot/carbon and symfony/http-foundation were dropped; the package now declares the illuminate/* components it actually uses. In a normal Laravel app the framework provides Carbon and HttpFoundation, so nothing changes — but if you consumed either only through this package's dependency graph, declare them explicitly in your composer.json.?Join, ?With, ?string. If you subclass or override handler methods, match the nullable types exactly or PHP will emit deprecations (8.4+) and potentially signature errors.Base-Model-Total is missing or wrong, check three things in order: the provider receives a builder rather than a relation result, the query still has its JOIN bindings intact after the count clone, and column qualification uses the join alias (relevant for polymorphic joins).Filter, Sort, Field, Join, With) and the count meta provider are the designed seams. Prefer extending/overriding those over post-processing the handler's output — the new suite covers them (99.2% lines, 100% methods), so behaviour there is the most predictable.How can I help you explore Laravel packages today?