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

Laravel Repository Laravel Package

chantouchsek/laravel-repository

Chantouch Sek's Laravel Repository adds a repository layer to Laravel applications, separating data access from business logic. It provides base repository classes and contracts that keep Eloquent queries organized, reusable, and easier to test.

View on GitHub
Deep Wiki
Context7

Getting Started

Install the package with Composer and let Laravel's package discovery register the service provider:

composer require chantouchsek/laravel-repository

If the package ships a config file, publish it before you start writing repositories so your defaults (paginator size, base model resolution, etc.) are under version control:

php artisan vendor:publish --tag=repository-config

Where to look first: the package's base repository class and its contract are the two files that matter. Everything else — generated stubs, artisan commands, config — hangs off those. Read the base class method signatures before reading the README examples; the signatures tell you exactly what you can override safely.

First use case: extract one fat controller. Pick a controller action that queries Eloquent directly, generate a repository + interface for that model, move the query in, and bind the interface in a service provider. Don't refactor the whole app — prove the pattern on one endpoint, get it under test, then expand.

Typical bootstrap shape:

// app/Providers/RepositoryServiceProvider.php
public function register(): void
{
    $this->app->bind(
        \App\Contracts\UserRepository::class,
        \App\Repositories\EloquentUserRepository::class
    );
}

Then inject the interface, not the concrete class:

public function index(UserRepository $users)
{
    return UserResource::collection($users->paginate(15));
}

Implementation Patterns

Interface-first, always. The value of a repository is the contract, not the class. Bind interfaces in a dedicated RepositoryServiceProvider so the mapping is one grep away rather than scattered across AppServiceProvider.

Compose query logic with criteria/filters. Day-to-day, most repository churn comes from listing endpoints that accumulate when() clauses. Push each filter into a small criteria object or a dedicated method (findActiveByTenant()) instead of growing a single search() method. This keeps the repository readable and makes each branch individually testable.

Keep transactions and business rules out of the repository. Repositories answer "give me data" and "persist this data." Wrap multi-repository writes in a service or action class with DB::transaction() at that layer. If you find yourself calling three repositories inside one another, the orchestration belongs one level up.

Testing pattern: because you depend on interfaces, swap the implementation in the container during tests:

$this->app->bind(UserRepository::class, InMemoryUserRepository::class);

This lets you test controllers and actions without touching the database. For the repositories themselves, test against a real (SQLite/in-memory) database — a repository that mocks Eloquent is testing nothing.

Decorator pattern for cross-cutting behaviour. Caching, logging, and metrics wrap cleanly around a repository contract. Implement the same interface, take the inner repository in the constructor, and bind the decorator. This is where the interface-first approach pays off in production.

Eager loading at the boundary. Whatever with()/load() strategy you use, decide it in the repository rather than letting controllers append relations. Otherwise consumers will bolt on ->with() calls the return type no longer supports once you swap to a non-Eloquent implementation.

Gotchas and Tips

Return types changed in 3.0.1. This patch release corrects return types on the base classes. If you sub-class the package's base repository or implement its interface in your own code, PHP's variance rules mean your overrides must declare compatible return types. Upgrading from 3.0.0 can therefore surface fatal errors in your own repository classes — run your suite immediately after bumping, and be explicit with return types (LengthAwarePaginator, ?Model, Collection) rather than relying on missing declarations.

Don't leak the query builder. The moment a repository method returns Builder or EloquentBuilder, the abstraction is dead and swapping implementations becomes impossible. Return domain values — models, collections, paginators, plain arrays.

Eloquent models inside your contracts are a judgement call. If your interfaces typehint Eloquent models, you can't swap to an API-backed implementation later. For most Laravel apps this is an acceptable trade; just make the decision consciously rather than accidentally.

Repository-per-model is an anti-pattern. The pattern buys you the most on models with complex, reused query logic. On a simple CRUD model it's a pass-through wrapper that costs indirection and file count. Apply it selectively.

Config and binding caches. After changing bindings in a service provider, php artisan config:clear and php artisan clear-compiled during local debugging; a stale cached binding manifests as "the wrong class is being resolved," which is confusing to diagnose.

Paginator type matters for responses. If you return a LengthAwarePaginator, JSON resources and ->links() behave consistently. Returning a raw Collection from a paginated endpoint forces every consumer to re-implement page metadata.

Extension points: the base repository's protected query hooks and any Criteria/filter contract are the intended seams. Prefer overriding those or composing criteria over copying base methods into your class — the latter silently breaks when the package changes its internals in a minor release.

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.
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator
equipc/laravel-email-database-log
adedsec/nova-translated-labels
wazza/laravel-db-encryption
hokny/laravel-generator
vonsogt/backup
jengo/queues
jeremykenedy/laravel-observability
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums