← Semua pembelajaran / Laravel Nol → Enterprise
Fase 3 · Arsitektur Laravel

Facade & helper

Facade adalah jalan pintas bertipe menuju objek di dalam container. Ia sangat nyaman, punya kemampuan tes yang bagus, dan menyembunyikan dependensi — ketiganya benar sekaligus.

Sumber asli laravel.com Resmi Rangkuman ~5 menit baca

Intisari

  • Cache::get() sebenarnya memanggil method biasa pada objek yang di-resolve dari container.
  • Karena lewat container, facade bisa diganti saat tes: Mail::fake(), Queue::fake(), Storage::fake().
  • Kelemahannya: dependensi jadi tidak terlihat di signature — kelas jadi lebih sulit dibaca dan dipakai ulang.
  • Aturan praktis: facade di controller dan route, injeksi konstruktor di kelas domain.
  • Real-time facade (Facades\App\...) memberi kemampuan fake() tanpa menulis facade sendiri.

Yang sebenarnya terjadi

Cache::put('kunci', 'nilai', 60);

// Setara dengan:
app('cache')->put('kunci', 'nilai', 60);

Kelas Cache hanya menyimpan satu string — nama layanan di container. Panggilan statis apa pun dilempar ke objek nyata lewat __callStatic. Karena itu seluruh lapisan facade tetap bisa diganti saat tes: yang kamu ganti adalah isi container, bukan kelas facade-nya.

Kekuatannya: fake()

public function test_pesanan_mengirim_email_dan_job(): void
{
    Mail::fake();
    Queue::fake();
    Storage::fake('s3');

    $this->post('/pesanan', [...]);

    Mail::assertSent(KonfirmasiPesanan::class, fn ($m) => $m->hasTo('[email protected]'));
    Queue::assertPushed(KirimInvoice::class);
    Storage::disk('s3')->assertExists('invoice/1.pdf');
}

Tidak ada email terkirim, tidak ada job diproses, tidak ada berkas naik ke S3 — tapi kamu punya kepastian bahwa kodenya melakukan ketiganya. Ini keuntungan facade yang paling nyata, dan alasan kenapa ia tidak pantas dihindari secara membabi buta.

Kelemahannya: dependensi tersembunyi

// Dengan facade — apa saja yang dipakai kelas ini? Harus dibaca seluruh isinya.
class HitungOngkir
{
    public function untuk(Pesanan $p): int
    {
        $tarif = Cache::remember("tarif:{$p->kota}", 3600,
            fn () => Http::get(config('services.ongkir.url'))->json());

        Log::info('ongkir dihitung', ['pesanan' => $p->id]);

        return $tarif['harga'];
    }
}

// Dengan injeksi — dependensinya tertulis di satu tempat, dan bisa diganti tanpa facade
class HitungOngkir
{
    public function __construct(
        private readonly Repository $cache,
        private readonly PenyediaOngkir $penyedia,
    ) {}
}
TempatPilihan yang sehatAlasan
Route closure, controller tipisFacade / helperSingkat, dan sudah pasti berjalan di dalam Laravel
Form request, middlewareFacadeSama
Kelas domain, action, serviceInjeksi konstruktorDependensinya jelas dan bisa diuji tanpa framework
Paket yang bisa dipakai ulangInjeksi konstruktorTidak mengikat diri ke facade aplikasi
Job dan listenerInjeksi di handle()Container tetap mengisinya otomatis

Facade, helper, dan objek — tiga bentuk hal yang sama

Cache::get('k');            app('cache')->get('k');       cache('k');
Session::get('k');          session('k');
Config::get('app.name');    config('app.name');
Response::json($d);         response()->json($d);
Redirect::route('beranda'); redirect()->route('beranda');
Auth::user();               auth()->user();               $request->user();

Untuk pengguna aktif, $request->user() adalah bentuk terbaik. Ia menyatakan bahwa identitas datang dari permintaan yang sedang diproses. auth()->user() membaca keadaan global — dan di worker mode, keadaan global adalah tempat kebocoran antar-pengguna bermula. Di dalam job antrean, keduanya bahkan tidak berlaku: job harus membawa user_id-nya sendiri.

Real-time facade

use Facades\App\Services\GerbangPembayaran;    // awalan "Facades\"

GerbangPembayaran::tagih($pesanan);            // kelasmu sendiri, dipanggil seperti facade
// dan bisa di-mock seperti facade bawaan
GerbangPembayaran::shouldReceive('tagih')->once()->andReturnTrue();

Berguna saat kamu perlu kemampuan mock tanpa mengubah signature kelas. Tetap saja, untuk kelas domain inti, injeksi konstruktor lebih jujur — orang berikutnya yang membaca kelasmu bisa melihat ketergantungannya tanpa membaca isinya.

Latihan: tulis satu controller yang memakai Mail::send(), lalu tulis tesnya dengan Mail::fake() dan Mail::assertSent(). Setelah hijau, refactor logikanya ke sebuah kelas action yang menerima Mailer lewat konstruktor — dan rasakan bedanya saat menulis tes yang kedua.

Rangkuman ini sengaja dipangkas ke bagian yang dipakai di roadmap. Buka sumber aslinya saat kamu butuh detail lengkap atau referensi parameter.