Introduction

All OstroJS application bootstrapping takes place in service providers. Service providers are used to bootstrap your own application as well as all of OstroJS' basic services.

But, exactly what do we mean when we say "bootstrapped"? We're talking about registering things like service container bindings, event listeners, middleware, and even routes in general. Service providers are the hub of your application's configuration.

A providers array may be found in the config/app.js file supplied with OstroJS. All of the service provider classes that will be loaded for your application are listed here. This Object lists a collection of OstroJS core service providers by default. The mailer, queue, cache, and other key OstroJS components are all bootstrapped using these services. Many of these providers are "delayed," which means they will only be loaded when the services they provide are truly needed, rather than on every request.

You'll learn how to create your own service providers and register them with your OstroJS application in this overview.

Writing Service Providers

The @ostro/support/serviceProvider class is extended by all service providers. A register and a boot mechanism are included in most service providers. You should only bind objects to the service container in the register method. You should never use the register method to register event listeners, routes, or any other piece of functionality.

The make: command in the Assistant CLI may be used to create a new provider.

command for the provider:

node assistant make:provider RiakServiceProvider

The Register Method

As previously stated, you should only bind objects into the service container using the register method. You should never use the register method to register event listeners, routes, or any other piece of functionality. Otherwise, you could inadvertently utilise a service offered by a service provider that hasn't yet loaded.

Let's look at an example of a simple service provider. You always have access to the $app property, which gives you access to the service container, from any of your service provider methods:

const Connection  = require('app/services/riak/connection');
const ServiceProvider = require('@ostro/support/serviceProvider');
class RiakServiceProvider extends ServiceProvider {
    /**
     * Register any application services.
     *
     * @return void
     */
    register() {
        this.$app.singleton('connection', function ($app) {
            return new Connection(config('riak'));
        });
    }
}

module.exports = AppServiceProvider

This service provider simply specifies a register method, which is used to specify an app/services/riak/connection implementation in the service container. Check out OstroJS's service container if you're not already familiar with its documentation.

 

The Boot Method

Instead of manually registering each container binding, you might want to utilise the bindings and singletons properties if your service provider registers numerous basic bindings. The framework will automatically check for these attributes and register their bindings when the service provider is loaded:

const ServiceProvider = require('@ostro/support/serviceProvider');
class ViewServiceProvider extends ServiceProvider {
    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    boot() {
        this.$app.view.boot(function () {
            //
        });
    }
}

module.exports = ViewServiceProvider

Registering Providers

The config/app.js configuration file contains a list of all service providers. You can list the class names of your service providers in the providers array in this file. This array contains a collection of OstroJS core service providers by default. The mailer, queue, cache, and other key OstroJS components are all bootstrapped using these services.

Add your provider to the array to register it:

'providers' : {
    // Other Service Providers
    'app/providers/viewServiceProvider',
},

Deferred Providers

You can opt to postpone your provider's registration until one of the registered bindings is really needed if your provider is only registering bindings in the service container. Because it is not loaded from the disc on every request, deferring the loading of such a provider will enhance the speed of your application.

OstroJS creates and saves a list of all postponed service provider services, as well as the name of the service provider class. OstroJS loads the service provider only when you try to resolve one of these services.

Implement the @ostro/support/deferrableProvider interface and offer a provides method to postpone the loading of a provider. The provider's service container bindings should be returned by the provides method:

const ServiceProvider = require('@ostro/support/serviceProvider');
const DeferrableProvider = require('@ostro/support/deferrableProvider');

class RiakServiceProvider extends implements(ServiceProvider, DeferrableProvider) {
    /**
     * Register any application services.
     *
     * @return void
     */
    register() {
        this.$app.singleton('connection', function ($app) {
            return new Connection($app['config']['riak']);
        });
    }

    /**
     * Get the services provided by the provider.
     *
     * @return array
     */
    provides() {
        return ['connection'];
    }
}

module.exports = RiakServiceProvider