Bayangkan Anda membangun fitur notifikasi. Hari ini kirim via email, bulan depan ditambah WhatsApp, tahun depan mungkin push notification. Kalau kode Anda langsung bergantung ke implementasi email spesifik, setiap perubahan akan memaksa Anda menyentuh banyak file sekaligus.
Di sinilah Contract di Laravel 12 berguna.
Apa Itu Contract di Laravel 12?
Contract di Laravel adalah sekumpulan interface yang mendefinisikan “kontrak perilaku” sebuah layanan. Mereka berada di namespace Illuminate\Contracts dan tidak berisi implementasi — hanya daftar method yang harus dipenuhi oleh siapapun yang mengimplementasikannya.
Singkatnya: Contract mendefinisikan apa yang bisa dilakukan, bukan bagaimana melakukannya.
Perbedaan Contract dan Interface Biasa
Secara teknis, Contract Laravel adalah interface PHP biasa. Yang membedakannya adalah tujuan dan skala: Contract Laravel menstandardisasi layanan inti framework (cache, queue, auth, storage, dll.) sehingga Anda bisa menukar implementasinya tanpa mengubah kode yang memakainya.
Contoh: Illuminate\Contracts\Cache\Store mendefinisikan method get, put, forget, dll. Baik driver Redis maupun Memcached sama-sama mengimplementasikan contract ini — kode Anda tidak perlu tahu mana yang aktif.
Membuat Contract Sendiri
Selain contract bawaan Laravel, Anda bisa membuat contract untuk layanan buatan sendiri. Contoh sederhana untuk layanan notifikasi:
// app/Contracts/NotificationServiceContract.php
namespace App\Contracts;
interface NotificationServiceContract
{
public function send(string $recipient, string $message): bool;
}
Lalu buat implementasinya:
// app/Services/EmailNotificationService.php
namespace App\Services;
use App\Contracts\NotificationServiceContract;
class EmailNotificationService implements NotificationServiceContract
{
public function send(string $recipient, string $message): bool
{
// logika kirim email
return true;
}
}
Binding Contract ke Service Container
Daftarkan binding di AppServiceProvider atau service provider khusus:
use App\Contracts\NotificationServiceContract;
use App\Services\EmailNotificationService;
public function register(): void
{
$this->app->bind(
NotificationServiceContract::class,
EmailNotificationService::class
);
}
Setelah itu, gunakan contract via dependency injection di controller atau class lain:
use App\Contracts\NotificationServiceContract;
class OrderController extends Controller
{
public function __construct(
private NotificationServiceContract $notifier
) {}
public function store(Request $request)
{
// ... proses order
$this->notifier->send($request->email, 'Pesanan diterima!');
}
}
Besok ketika Anda ingin ganti ke WhatsApp, cukup buat WhatsAppNotificationService, ubah satu baris binding di service provider — tidak ada yang berubah di controller.
Kapan Sebaiknya Menggunakan Contract?
Contract paling berguna ketika:
- Implementasi layanan bisa berubah di masa depan (storage, payment gateway, notifikasi)
- Anda ingin membuat unit test yang tidak bergantung ke implementasi nyata (mock mudah dibuat dari interface)
- Tim besar — contract menjadi “dokumen hidup” yang mendefinisikan API internal antar modul
Untuk fungsi sederhana yang tidak akan berubah, Contract justru menambah kompleksitas yang tidak perlu. Gunakan dengan pertimbangan, bukan sebagai aturan baku.
Contract vs Facade di Laravel
Laravel punya Facade yang memberikan akses statis ke layanan container. Contract dan Facade sering digunakan untuk tujuan serupa, tapi berbeda pendekatan. Facade lebih ringkas untuk kode cepat; Contract lebih eksplisit dan mudah di-mock saat testing. Untuk aplikasi skala besar dengan banyak unit test, Contract umumnya lebih direkomendasikan.
Kalau Anda sedang membangun aplikasi Laravel dan butuh konsultasi arsitektur atau tim pengembang, kami di Arrazy Inovasi siap membantu.
Leave a Reply