Traits para Controllers de Laravel facilitando uso da lib `prettus/l5-repository`
gblix/laravel-controller-repository-traits is a Laravel package for traits para controllers de laravel facilitando uso da lib `prettus/l5-repository`.
It currently has 1 GitHub stars and 8.489 downloads on Packagist (latest version 1.9.0).
Install it with composer require gblix/laravel-controller-repository-traits.
Discover more Laravel packages by gblix
or browse all Laravel packages to compare alternatives.
Last updated
Controller traits for Laravel that streamline building REST APIs on top of
prettus/l5-repository. The package wires
controllers, repositories, Fractal presenters and validators together so each CRUD endpoint
becomes a one-liner with well-defined customization hooks.
| Package version | Laravel | PHP | prettus/l5-repository |
|-----------------|-----------|-------|-----------------------|
| 1.8.x | 12, 13 | ≥ 8.3 | ^2.10 \|\| ^4.0 |
| 1.7.x (beta) | 12 | ≥ 8.3 | ^2.10 |
| 1.6.x | 11 | ≥ 8.3 | ^2.9.1 |
Laravel 13 requires prettus/l5-repository 4.x (2.x/3.x cap at
illuminate/* ^12). On Laravel 12 either prettus major works, which lets you upgrade this package first and migrate to prettus 4.x at your own pace.
prettus/l5-repository 4.0 bundles the Prettus\Validator\* classes inside the package itself.
Do not require prettus/laravel-validation alongside l5-repository 4.x — both define the
same Prettus\Validator namespace and composer will report ambiguous class resolution. Remove
prettus/laravel-validation from your app's composer.json when moving to prettus 4.x; no code
changes are needed (Prettus\Validator\LaravelValidator and friends keep the same API).
composer require gblix/laravel-controller-repository-traits
Register the macro service provider (not auto-discovered) to enable the
paginateNoLimit/paginateAll Eloquent builder macros:
// config/app.php (or bootstrap/providers.php on Laravel 11+)
Gblix\ServiceProviders\EloquentMacroServiceProvider::class,
Six traits under Gblix\Controllers\ApiTraits implement the default REST actions. They expect
the controller to expose a $repository property implementing
Gblix\Repository\Contracts\RepositoryInterface:
use Gblix\Controllers\ApiTraits;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Symfony\Component\HttpFoundation\Response;
class UsersController extends Controller
{
use ApiTraits\Retrieve; // index()
use ApiTraits\Read; // getCurrentEntryId() + shared read hooks
use ApiTraits\Show; // show()
use ApiTraits\Create; // runStore() — you implement store()
use ApiTraits\Update; // runUpdate() — you implement update()
use ApiTraits\Delete; // destroy()
protected UserRepository $repository;
public function __construct(UserRepository $repository)
{
$this->repository = $repository;
}
public function store(Request $request): Response
{
return $this->runStore($request, CreateUserAction::class);
}
public function update(Request $request): Response
{
return $this->runUpdate($request, UpdateUserAction::class);
}
}
Create/Update/Delete dispatch a "job" object: Laravel Actions v2 (asController()),
Laravel Actions v1 (actingAs()->run()) and plain classes with run()/handle(array $data)
are all supported.
Retrieve)index() paginates by default and honors the limit query parameter:
| limit | Result |
|----------------|----------------------------------------------------------------------------|
| absent | paginate() with the default page size (repository.pagination.limit) |
| 0 | paginateNoLimit() — pagination metadata only, empty data |
| -1 | paginateAll() — every record plus pagination metadata |
| any other int | paginate(limit) |
If the repository's model defines scopeFilter, the request input is forwarded to it through
EntityFilterCriteria (a JSON filter query parameter is decoded automatically).
| Hook | Trait | Purpose |
|------|-------|---------|
| pushIndexCriteria($repository, $request) | Retrieve | Extra criteria for index |
| pushEntityRelations($repository, $request) | Retrieve | Eager-load relations |
| filterRequestToEntityFilter($request, $data) | Retrieve | Mutate filter data |
| willIndexPaginate() | Retrieve | Return false to disable pagination |
| getRetrievePresenter() / getShowPresenter() / getStorePresenter() / getUpdatePresenter() | each | Per-action presenter override |
| pushReadCriteria($repository) | Read | Criteria shared by show/update/delete |
| pushShowCriteria($repository) / pushDestroyCriteria($repository) | Show / Delete | Per-action criteria |
| $routeKey / $resource properties | Read | Customize how the entry id is read from the route |
Extend Gblix\Repository\BaseRepository (which extends
Prettus\Repository\Eloquent\BaseRepository):
use Gblix\Repository\BaseRepository;
class UserRepository extends BaseRepository
{
public function model()
{
return User::class;
}
public function presenter()
{
return UserPresenter::class;
}
public function validator()
{
return UserValidator::class;
}
}
Extras on top of prettus: exists($id), cursor(), paginateNoLimit(), paginateAll() and
collectionPresenter() (an optional presenter class used for collections).
Extend Gblix\Presenters\FractalPresenter and return a
league/fractal transformer:
use Gblix\Presenters\FractalPresenter;
use League\Fractal\TransformerAbstract;
class UserPresenter extends FractalPresenter
{
public function getTransformer(): TransformerAbstract
{
return new UserTransformer();
}
}
Extend Gblix\Validators\BaseValidator (a Prettus\Validator\LaravelValidator).
passesOrFail() throws Laravel's own Illuminate\Validation\ValidationException, so failures
render as standard 422 responses:
use Gblix\Validators\BaseValidator;
use Prettus\Validator\Contracts\ValidatorInterface;
class UserValidator extends BaseValidator
{
protected $rules = [
ValidatorInterface::RULE_CREATE => ['name' => 'required'],
ValidatorInterface::RULE_UPDATE => ['name' => 'sometimes|required'],
];
}
Gblix\Repositories\Criteria\EntityFilterCriteria forwards an array to the model's
scopeFilter:
public function scopeFilter(Builder $query, ?array $data): Builder
{
if (isset($data['name'])) {
$query->where('name', 'like', "%{$data['name']}%");
}
return $query;
}
All tests run inside Docker — nothing is executed on the host machine. One command runs every supported combination (CI uses the same script):
./scripts/test-all.sh
| Matrix | PHP | Laravel | prettus/l5-repository |
|--------|-----|---------|-----------------------|
| test-l13 | 8.4 | 13 | 4.x |
| test-l12 | 8.3 | 12 | 4.x |
| test-l12-prettus2 | 8.3 | 12 | 2.x |
Individual matrices can be run with docker compose run --rm <matrix>. The non-canonical
matrices use isolated composer-<matrix>.json/.lock/vendor-<matrix>/ artifacts
(gitignored) so they never clobber the committed lock file.
master via pull request (CI runs all three matrices).git tag 1.8.0 && git push origin 1.8.0).Release workflow re-runs the matrices and creates the GitHub Release; Packagist syncs
automatically.