When and Why to Use Contracts in Laravel
Imagine your application supports multiple payment providers:
- Razorpay
- Stripe
- PayPal
Instead of hardcoding one provider, define a contract.
Step 1: Create Contract
interface PaymentGateway
{
public function charge(float $amount);
}
Step 2: Implement It
class RazorpayService implements PaymentGateway
{
public function charge(float $amount)
{
// Razorpay logic
}
}
Later, you can create:
class StripeService implements PaymentGateway
{
public function charge(float $amount)
{
// Stripe logic
}
}
Step 3: Bind in Service Container
$this->app->bind(PaymentGateway::class, RazorpayService::class);
Now Laravel automatically injects it.
Step 4: Use It Anywhere
public function store(PaymentGateway $payment)
{
$payment->charge(500);
}
You can switch providers by changing only one binding line.
No controller changes needed.
š¹ Why Contracts Are Powerful
They:
- Reduce tight coupling
- Make swapping implementations easy
- Improve unit testing (mock interfaces easily)
- Keep architecture clean
š¹ When NOT to Use Contracts
Avoid contracts when:
- Logic is very small
- No chance of swapping implementation
- The app is extremely simple