everycheck/api-rest-utils
A Symfony utility package offering a JSON response builder with common API statuses and custom headers, plus a paginated repository trait for filtering, ordering, and searching entities across joins.
Verdict: reference implementation only — do not adopt as a dependency.
ResponseBuilder that emits Symfony\Component\HttpFoundation\Response objects with JSON bodies, and a Doctrine repository trait for filtered/ordered pagination. Neither is Laravel-idiomatic: the README examples use Symfony's service container ($this->get('jms_serializer')), Doctrine's EntityManager/getRepository(), and Symfony Form error parsing. In a Laravel codebase you would be importing a foreign architecture for two small pieces of plumbing that Laravel already solves natively (response()->json(), API Resources, LengthAwarePaginator, query scopes).Illuminate\Http\Response extends Symfony's Response, and Laravel's router will normalize a returned Symfony response — so a naive return (new ResponseBuilder(...))->ok($data); would technically render. But the constructor's hard dependency on a JMS Serializer instance (uncommon in Laravel) and the Doctrine-bound trait mean you'd be fighting the framework on both halves. The pragmatic path is a fork-and-port, not an install.symfony/http-foundation versions that conflict with Laravel 10/11 (Symfony 6/7). An composer require may simply fail resolution, or force a downgrade elsewhere in the tree.symfony/http-foundation version constraints does composer.json declare?formError, forbiddenAcl, conflict) aligned with our existing API contract, or will they introduce a fourth error shape?ok, created, deleted, notFound, badRequest, unauthorized, forbidden, conflict, formError) is a reasonable API error taxonomy that most teams converge on anyway; the value is the naming convention, not the implementation. The addHeaders() fluent pattern is trivially reproducible as a Laravel Response macro or a small ApiResponse facade.composer.json. Treat the repo as a design reference and a source of copy-paste candidates.App\Http\ApiResponse using response()->json($payload, $status, $headers) with a consistent envelope: { data, meta } on success, { error: { code, message, details } } on failure. Wire it into the exception handler so ModelNotFoundException, AuthorizationException, and ValidationException map to notFound / forbidden / formError equivalents automatically.JsonResource / ResourceCollection). This removes the single most awkward dependency in the package and gets you conditional relationships, pagination metadata, and sparse fieldsets for free.Filterable trait plus ->when($request->filled('sort'), ...) and ->paginate(). Critically, implement a field allow-list rather than translating request keys directly into orderBy / where columns.composer.json proves otherwise. If any Laravel service needs to co-exist, verify symfony/http-foundation resolution first — this is the single most likely hard blocker to a straightforward require.ResponseBuilder to ApiResponse + exception handler mapping → (4) port serialization to API Resources → (5) port pagination to Eloquent scopes with allow-listing → (6) add contract tests on status codes and envelope shape → (7) delete the package reference. Total estimate: 3–5 engineer-days for a small team, most of it in contract tests rather than code.ResponseBuilder is stateless and allocation-only, so throughput impact is noise against serialization and DB time. The real scaling concerns are inherited from the design: (a) JMS Serializer is materially slower and heavier than Laravel's native JSON encoding for large collections; (b) a dynamic filter/order trait without index-aware allow-listing will produce full-table scans and unpredictable query plans as tables grow; (c) uniform JSON errors on every path means no streaming or partial-response optimization — fine for CRUD, a ceiling for high-volume exports.composer update breaking on a Symfony major bump (package pinned to EOL components) — likely the first incident.conflict vs badRequest) are conventions with no tests enforcing them, so they will diverge across services.Bottom line for a TPM: the score (0.0025), archived status, single-digit stars, zero dependents, and Symfony-only scope all point the same direction — this is a small piece of prior art worth 30 minutes of reading and zero lines in composer.json. Extract the API verb taxonomy and the fluent header pattern, reimplement them natively in Laravel, and close the item.
How can I help you explore Laravel packages today?