Understanding Laravel Contracts: When to Use Interfaces Over Facades
Laravel contracts are interface definitions for core services such as cache, queue, and mail, offering decoupled implementations and testability; this guide explains their purpose, differences from facades, when to prefer contracts, and provides a comprehensive list of available contracts with examples.
Introduction
Laravel contracts are a set of interfaces that define core services such as cache, queue, and mail. Each contract has a concrete implementation provided by the framework, allowing developers to type‑hint dependencies and write test‑friendly code.
Contracts vs. Facades
Facades offer a static‑like syntax for accessing services without explicit type‑hinting, while contracts require explicit dependency injection. Facades are convenient, but contracts make dependencies clear and are preferable when building reusable packages.
In most applications either approach works; however, when creating a package, contracts are recommended for easier testing.
When to Use Contracts
Choosing between contracts and facades is largely a matter of personal or team preference, but contracts provide loose coupling and simplicity.
Loose Coupling
Consider tightly coupled cache code:
<code>cache = $cache; /** * Get order by ID * @param int $id * @return Order */ public function find($id) { if ($this->cache->has($id)) { // } }</code>Replacing the underlying cache implementation would require code changes. By depending on a contract instead, the implementation can be swapped without modifying consuming code.
<code>cache = $cache; }</code>Simplicity
Having services defined by simple interfaces makes it easy to understand what functionality is available and serves as concise documentation.
How to Use Contracts
Implement a contract by type‑hinting it in a class constructor. The service container will resolve and inject the appropriate implementation.
Example with an event listener:
<code>redis = $redis; /** * Handle the event. * @param OrderWasPlaced $event * @return void */ public function handle(OrderWasPlaced $event) { // }</code>Key Contracts and Their Facades
Illuminate\Contracts\Auth\Access\Gate : Gate
Illuminate\Contracts\Auth\Factory : Auth
Illuminate\Contracts\Cache\Factory : Cache
Illuminate\Contracts\Cache\Repository : Cache::driver()
Illuminate\Contracts\Bus\Dispatcher : Bus
Illuminate\Contracts\Bus\QueueingDispatcher : Bus::dispatchToQueue()
Illuminate\Contracts\Broadcasting\Factory : Broadcast
Illuminate\Contracts\Encryption\Encrypter : Crypt
Illuminate\Contracts\Events\Dispatcher : Event
Illuminate\Contracts\Filesystem\Factory : Storage
Illuminate\Contracts\Hashing\Hasher : Hash
Illuminate\Contracts\Mail\Mailer : Mail
Illuminate\Contracts\Notifications\Dispatcher : Notification
Illuminate\Contracts\Routing\UrlGenerator : URL
Illuminate\Contracts\Session\Session : Session::driver()
Python Programming Learning Circle
A global community of Chinese Python developers offering technical articles, columns, original video tutorials, and problem sets. Topics include web full‑stack development, web scraping, data analysis, natural language processing, image processing, machine learning, automated testing, DevOps automation, and big data.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.