โ† Semua pembelajaran / Laravel Nol โ†’ Enterprise
Fase 3 ยท Arsitektur Laravel

Service provider

Provider adalah satu-satunya tempat di Laravel yang berjalan sebelum apa pun terjadi. Yang perlu dipahami cuma satu hal: perbedaan antara register dan boot, dan kenapa mengabaikannya menghasilkan bug yang tidak konsisten.

Sumber asli laravel.com Resmi Rangkuman ~5 menit baca

Intisari

  • register() hanya mengikat ke container. Jangan memakai layanan lain di sini.
  • boot() berjalan setelah semua provider ter-register โ€” di sinilah konfigurasi sesungguhnya dilakukan.
  • Provider didaftarkan di bootstrap/providers.php.
  • Paket menemukan providernya sendiri lewat package discovery; kamu jarang perlu mendaftarkannya.
  • Fase 8: di worker mode, kedua method ini hanya berjalan sekali seumur proses โ€” bukan tiap permintaan.

Dua method, dua aturan

class AppServiceProvider extends ServiceProvider
{
    public function register(): void
    {
        // BOLEH: mengikat. Tidak ada yang dijalankan sekarang.
        $this->app->singleton(GerbangPembayaran::class, MidtransGateway::class);

        // JANGAN: memakai layanan lain. Provider yang menyediakannya mungkin
        // belum ter-register saat baris ini dieksekusi.
        // config('...') di sini masih berisiko; Route::, Gate::, View:: apalagi.
    }

    public function boot(): void
    {
        // Semua provider sudah ter-register. Di sini semuanya aman dipakai.
        Model::preventLazyLoading(! app()->isProduction());
        Model::unguard(false);

        Gate::define('kelola-toko', fn (User $u) => $u->peran === 'admin');

        Validator::extend('kode_pos_id', fn ($a, $v) => (bool) preg_match('/^\d{5}$/', $v));

        View::share('namaToko', config('toko.nama'));

        RateLimiter::for('api', fn (Request $r) =>
            Limit::perMinute(60)->by($r->user()?->id ?: $r->ip()));
    }
}

Kenapa aturan ini tidak boleh dilanggar. Bug yang dihasilkannya tidak konsisten: kodenya jalan hari ini, lalu suatu hari kamu memasang paket baru, urutan pemuatan provider bergeser, dan tiba-tiba register()-mu memakai layanan yang belum ada. Errornya muncul jauh dari penyebabnya. register mengikat, boot memakai โ€” dua kata itu cukup.

Mendaftarkan provider

// bootstrap/providers.php
return [
    App\Providers\AppServiceProvider::class,
    App\Providers\TokoServiceProvider::class,
];
php artisan make:provider TokoServiceProvider   # sekaligus mendaftarkannya

Paket pihak ketiga tidak perlu ditambahkan ke daftar ini. Composer mengumumkan providernya lewat blok extra.laravel di composer.json paket tersebut, dan Laravel menemukannya sendiri โ€” inilah kenapa composer require sebuah paket Laravel biasanya langsung bisa dipakai.

Apa yang layak tinggal di sini

UrusanMethodContoh
Interface โ†’ implementasiregisterbind(Gerbang::class, Midtrans::class)
Kebijakan modelbootpreventLazyLoading, shouldBeStrict
Aturan otorisasi globalbootGate::define(...)
Rate limiter bernamabootRateLimiter::for('api', ...)
Aturan validasi kustombootValidator::extend(...)
Komponen Blade & direktifbootBlade::directive(...)
Pendengar eventbootEvent::listen(...)
Macro pada kelas frameworkbootStr::macro(...)

Deferred provider

class LaporanServiceProvider extends ServiceProvider implements DeferrableProvider
{
    public function register(): void
    {
        $this->app->singleton(MesinLaporan::class);
    }

    public function provides(): array
    {
        return [MesinLaporan::class];      // baru dimuat saat kelas ini benar-benar diminta
    }
}

Provider yang di-defer tidak dimuat sampai layanannya dibutuhkan. Di mode PHP-FPM ini mengurangi biaya bootstrap setiap permintaan. Di worker mode manfaatnya mengecil โ€” bootstrap hanya sekali โ€” tapi tetap berguna untuk perintah Artisan yang tidak butuh separuh aplikasi.

Bacaan silang untuk Fase 8. Di Octane, register() dan boot() berjalan satu kali saat worker menyala. Konsekuensinya: apa pun yang kamu baca dari $request di dalam provider akan membeku pada permintaan pertama dan salah untuk semua permintaan berikutnya. Provider tidak boleh tahu apa-apa tentang permintaan yang sedang berjalan.

Latihan: buat TokoServiceProvider yang mendefinisikan satu Gate, satu View::share, dan satu Str::macro. Lalu sengaja pindahkan Gate::define(...) ke register(), jalankan aplikasinya, dan baca errornya โ€” pengalaman lima menit yang membuat aturan di atas melekat.

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