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

Rest Bundle Laravel Package

gollumsf/rest-bundle

gollumsf/rest-bundle is a Symfony bundle for building RESTful APIs with less boilerplate. It helps configure resource endpoints, handle requests, serialize responses, and keep JSON API output consistent across services.

View on GitHub
Deep Wiki
Context7

Getting Started

  • Check the framework before the features. This is a Symfony bundle (type: symfony-bundle), not a Laravel package. It has no service provider, no facade, and nothing to publish. composer require gollumsf/rest-bundle may resolve dependencies inside a Laravel app, but the bundle's boot logic only runs through a Symfony Kernel — in Laravel it is inert.
  • Where to look first: the repo's composer.json (type + require block), the bundle/extension class in src/ (that's the real entry point), the README for the attribute/annotation syntax, docs/Sorting.md (the most useful reference — see below), and the LICENSE file. The license matters more than the API surface here.
  • First realistic use case: you maintain or are migrating a Symfony service that already uses it, and you need to understand its REST conventions. Or you're mining it as a design reference — the sorting/pagination layer is now genuinely instructive.
  • If you're building in Laravel, the first "use" is replication, not installation: routes/api.php + Route::apiResource, a FormRequest, a JsonResource, and a JSON error renderer in bootstrap/app.php via withExceptions. That covers the bulk of what a small REST bundle provides.
  • If you genuinely need both stacks, isolate the bundle in a separate Symfony app and call it over HTTP. Do not attempt to boot a Symfony bundle inside Laravel's lifecycle.

Implementation Patterns

The bundle's model — thin actions, framework-handled deserialization/serialization, standardized error payloads, server-driven sort/paginate — maps cleanly onto Laravel primitives:

Bundle concept Laravel equivalent
Single-action REST controller Invokable controller or one route per action
Request body deserialization FormRequest (validation + authorize) with a toDto() method, or spatie/laravel-data for attribute-driven mapping
Response serialization JsonResource / ResourceCollection — never return Eloquent models raw
Error envelope withExceptions() / render() forcing {error: {code, message, details}} for API routes
Query-string sorting across relations Explicit orderBy allow-list in a query builder / spatie/laravel-query-builder
Pagination + count over to-many joins ->distinct()->count(), then page on the entity, not the join
Route versioning / negotiation /api/v1 prefix plus middleware inspecting Accept

Day-to-day workflow: keep one triad per resource (Request, Resource, Controller), register behind auth:sanctum, and write feature tests with $this->getJson(). This is the discipline the bundle is trying to enforce — you can get it without the dependency.

The v4.2.1 fix is worth stealing as a pattern. If you sort or paginate a Laravel query that joins a hasMany (or any to-many), you hit the exact same bug the bundle just fixed: count() over-counts rows, and limit truncates entities nondeterministically because duplicates land inside the window. The bundle's fix is a good template:

  • count with DISTINCT on the root entity's identifier, not COUNT(*)
  • when ordering across a collection, sort on an aggregate of the joined column (MIN for ascending, MAX for descending), grouped by the root id, so the fan-out collapses before the LIMIT is applied
  • keep it additive — groupBy/having/aggregate on top of the existing QueryBuilder rather than rewriting it into subqueries (which is what Doctrine's Paginator does, and why the bundle rejected it)

Your equivalent in Eloquent: ->select('authors.*')->selectRaw('MIN(books.title) as sort_key')->groupBy('authors.id')->orderBy('sort_key')->paginate($perPage) — plus a DISTINCT count. Prefer this over ->with() + load-and-slice for large datasets.

Hybrid integration tip: go contract-first. Publish an OpenAPI spec, implement it in Symfony with the bundle, consume it from Laravel with Http::retry()->timeout(). Treat it as a service boundary, not a library.

If you are actually in Symfony: attribute routing on the action, one DTO per action, let the bundle's normalizer handle output, and add a kernel exception listener so domain exceptions map to the same error shape. Consistency of the error envelope is the only thing that reliably pays off.

Gotchas and Tips

  • License is the blocker. GPL-3.0 is strong copyleft. For a distributed Laravel app it can force source disclosure; even for internal SaaS it warrants legal review. Nearly every Laravel package you'd reach for is MIT — this is a hard stop for most teams.
  • Adoption is still effectively zero. One star, zero dependents. Even with recent activity there are no tutorials, no StackOverflow answers, no third-party bug reports. You are the QA team, and the bus factor is one.
  • Actively maintained, though. v4.2.1 (452 tests, 100% coverage, Symfony 6.4–8.1, PHP 8.2/8.4) is a real signal — the earlier caution about anomalous release metadata is no longer the key concern. If you adopt it in Symfony, this is a working piece of software, not abandonware.
  • The scope of the fix is narrower than it looks. Only queries that previously crossed a to-many relation change SQL. Single-column sorts and to-one relations are untouched, and any existing code that hit the bug was returning wrong results — expect page counts and page contents to shift for those endpoints. That's a fix, not a regression, but it will look like a data change to downstream clients.
  • Extension points don't port. Compiler passes, tagged services, custom normalizers, and event subscribers are Symfony DI concepts. They have no analog in Laravel's container, and running two containers in one process is a debugging nightmare.
  • "Very simple" is the honest warning. Expect to write your own validation, pagination, error envelopes, auth wiring, and OpenAPI docs regardless. The bundle saves glue, not a layer.
  • Debugging in Laravel provides no leverage — no profiler, no debug commands; failures surface as boot-time container errors rather than useful messages.
  • Steal the shape, not the code. Single-action controllers + DTO + normalizer, and the v4.2.1 aggregate-sort pattern for joined collections, are a good template. Copy the structure into Laravel; skip the dependency.
  • If you do adopt it in Symfony, pin exact versions and wrap it behind your own interfaces so removal later is a single-file change.
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.
frankyso/ipaymu
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
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