Articles

Service Providers in Laravel: what they are and how to use Service Providers in Laravel

Laravel service providers are the central place where the application is started. That is, core Laravel services and application services, classes, and their dependencies are placed in the service container via providers. 

In other words, service providers are like a funnel through which we pour "class" fuel into a tank called the "service container" of an engine called Laravel.

Example

If we open config/app.php we will see an array with the name "provider"

'providers' => [

        /*
        * Laravel Framework Service Providers...
        */
        Illuminate\Auth\AuthServiceProvider::class,
        Illuminate\Broadcasting\BroadcastServiceProvider::class,
        Illuminate\Bus\BusServiceProvider::class,
        Illuminate\Cache\CacheServiceProvider::class,
        Illuminate\Foundation\Providers\ConsoleSupportServiceProvider::class,
        Illuminate\Cookie\CookieServiceProvider::class,
        .
        .
        .
],

These are some of the service providers provided together with laravel, i.e. basic services that are placed in the service container.

when the service provider are they performed?

If we look at the documentation on request lifecycle , the following files are executed at the start:

  • public/index.php
  • bootstrap/app.php
  • app/Http/Kernel.php and its Middlewares
  • Service Providers: content of this article

Which service provider are they loaded? 

They are those definites in the array config/app.php:

return [
 
    // ... other configuration values
 
    'providers' => [
 
        /*
         * Laravel Framework Service Providers...
         */
        Illuminate\Auth\AuthServiceProvider::class,
        Illuminate\Broadcasting\BroadcastServiceProvider::class,
 
        // ... other framework providers from /vendor
        Illuminate\Validation\ValidationServiceProvider::class,
        Illuminate\View\ViewServiceProvider::class,
 
        /*
         * PUBLIC Service Providers - the ones we mentioned above
         */
        App\Providers\AppServiceProvider::class,
        App\Providers\AuthServiceProvider::class,
        // App\Providers\BroadcastServiceProvider::class,
        App\Providers\EventServiceProvider::class,
        App\Providers\RouteServiceProvider::class,
 
    ],
 
];

As we can see, there is a list of service provider not public in the folder /vendor, we should neither touch nor modify them. Those that interest us are below, with BroadcastServicerProvider disabled by default, probably because it is rarely used.

All these service providers run from top to bottom, repeating the list twice:

  • The first iteration is looking for an optional method register(), useful for (eventually) executing something configured before the method boot().
  • the second iteration executes the method boot() of all providers. Again, one by one, top to bottom, of the array 'providers'.
  • Finally, after all the service providers have been processed, Laravel moves on to parsing the path (route), running the controller, using templates, etc.

Service Providers Laravel predefinor

I Service Providers included in Laravel, are all those present in the folder app/Providers:

  • AppServiceProvider
  • AuthServiceProvider
  • BroadcastServiceProvider
  • EventServiceProvider
  • RouteServiceProvider

They are all PHP classes, each related to its own topic: App, Auth, Broadcasting, Events e Routes. But they all have one thing in common: method boot().

Inside that method, we can write any code related to any of those sections: auth, events, route, etc. In other words, Service Providers are just classes to register some global functionality.

They're separate as "providers" because they run very early in the application lifecycle, so something global is convenient here before the executing script gets to Models or Controllers.

Most of the functionality is in the RouteServiceProvider, here is the code:

class RouteServiceProvider extends ServiceProvider
{
    public const HOME = '/dashboard';
 
    public function boot()
    {
        $this->configureRateLimiting();
 
        $this->routes(function () {
            Route::prefix('api')
                ->middleware('api')
                ->group(base_path('routes/api.php'));
 
            Route::middleware('web')
                ->group(base_path('routes/web.php'));
        });
    }
 
    protected function configureRateLimiting()
    {
        RateLimiter::for('api', function (Request $request) {
            return Limit::perMinute(60)->by($request->user()?->id ?: $request->ip());
        });
    }
}

This is the class where the files are configured route, with routes/web.phproutes/api.php included by defaultdefinita. Note that for the API there are also different configurations: Endpoint prefix /api and middleware api for all routes.

We can edit the service providers, which are not in the folder /vendor. Customizing these files is done when you have many paths and want to separate them into specific files. You create routes/auth.php and put the paths there, then you "enable" that file in the method boot() di RouteServiceProvider, just add the third sentence:

`Route::middleware('web') // or maybe you want another middleware?
    ->group(base_path('routes/auth.php'));

AppServiceProvider it's empty. A typical example of adding code AppServiceProvider, is about disabling lazy loading in Eloquent . To do this, you just need add two lines in the method boot():

Innovation newsletter
Don't miss the most important news on innovation. Sign up to receive them by email.
// app/Providers/AppServiceProvider.php
use Illuminate\Database\Eloquent\Model;
 
public function boot()
{
    Model::preventLazyLoading(! $this->app->isProduction());
}

This will throw an exception if a relationship model is not loaded.

Create your own service provider custom

In addition to the pre filesdefinites, we can easily create a new one Service Provider, related to other topics than those predefifinished as auth/event/routes.

A fairly typical example is the view configuration Blade. We can create a directive Blade, and then add that code into the method boot() of any service provider, including the default AppServiceProvider. Let's now create a ViewServiceProvider separate.

We can generate it with this command:

php artisan make:provider ViewServiceProvider

Which will generate the class so predefinite:

namespace App\Providers;
 
use Illuminate\Support\ServiceProvider;
 
class ViewServiceProvider extends ServiceProvider
{
    /**
     * Register services.
     *
     * @return void
     */
    public function register()
    {
        //
    }
 
    /**
     * Bootstrap services.
     *
     * @return void
     */
    public function boot()
    {
        //
    }
}

As we can see inside there are two methods:

The register() method

The register() method allows us to definish links to our service container. For example, in the following code:

public function register()
{
    $this->app->singleton(my_class, function($app){
        return new MyClass($app);
    });
}

$this->app is a global variable in laravel that a singleton class can access through the app.

Singleton is a feature. When applying this feature, we are informing the application that whatever class is passed as a parameter in the app should only have one instance in the whole application. This means that MyClass will be resolved once and will have only one instance, which can be accessed using the my_class variable.

The boot() method

The boot() method allows you to access all services previously registered using the register method. You can then include the entire service in your application using this method.

Going back to the previous example, let's remove the method register() and within boot() add the Blade directive code:

use Illuminate\Support\Facades\Blade;
 
public function boot()
{
    Blade::directive('datetime', function ($expression) {
        return "<?php echo ($expression)->format('m/d/Y H:i'); ?>";
    });
}

Another example of ViewServiceProvider it concerns View Composers, here is the snippet from the official Laravel site :

use App\View\Composers\ProfileComposer;
use Illuminate\Support\Facades\View;
use Illuminate\Support\ServiceProvider;
 
class ViewServiceProvider extends ServiceProvider
{
    public function boot()
    {
        // Using class based composers...
        View::composer('profile', ProfileComposer::class);
 
        // Using closure based composers...
        View::composer('dashboard', function ($view) {
            //
        });
    }
}

To run, this new provider must be added/registered to the in provider array config/app.php:

return [
    // ... other configuration values
 
    'providers' => [
 
        App\Providers\AppServiceProvider::class,
        App\Providers\AuthServiceProvider::class,
        // App\Providers\BroadcastServiceProvider::class,
        App\Providers\EventServiceProvider::class,
        App\Providers\RouteServiceProvider::class,
 
        // Add your provider here
        App\Providers\ViewServiceProvider::class,
    ],
];

Ercole Palmeri

You may also be interested in:

Innovation newsletter
Don't miss the most important news on innovation. Sign up to receive them by email.

Latest Articles

The Future is Here: How the Shipping Industry is Revolutionizing the Global Economy

The naval sector is a true global economic power, which has navigated towards a 150 billion market...

May 1, 2024

Publishers and OpenAI sign agreements to regulate the flow of information processed by Artificial Intelligence

Last Monday, the Financial Times announced a deal with OpenAI. FT licenses its world-class journalism…

April 30 2024

Online Payments: Here's How Streaming Services Make You Pay Forever

Millions of people pay for streaming services, paying monthly subscription fees. It is common opinion that you…

April 29 2024

Veeam features the most comprehensive support for ransomware, from protection to response and recovery

Coveware by Veeam will continue to provide cyber extortion incident response services. Coveware will offer forensics and remediation capabilities…

April 23 2024