Configuration

The ConfigurationService offers a centralized storage to the configuration of the different components of Banquette.

You can import it from @banquette/config:

import { Injector } from '@banquette/dependency-injection';
import { ConfigurationService } from '@banquette/config';

const config = Injector.Get(ConfigurationService);

Getting

Packages that have a configuration expose a Symbol that you can use to get the current values in use.

The naming rule is always the same: PascalCasedopen in new window name of the module followed by ConfigurationSymbol. So for example:

  • http package: HttpConfigurationSymbol
  • storage package: StorageConfigurationSymbol
  • etc.

All packages don't have a configuration object.

Get a configuration object

Let's take for example the http package. To get its configuration, do:

import { HttpConfigurationInterface, HttpConfigurationSymbol } from "@banquette/http";

const httpConfig = config.get<HttpConfigurationInterface>(HttpConfigurationSymbol);
// ...

Get a configuration value

The configuration object returned in the previous example is simply literal object. So you can access any value inside like you would expect:

httpConfig.requestTimeout; // 30000

Even if it's not the best practice, you can also access a value by string, from the ConfigurationService object itself, like so:

const config = Injector.Get(ConfigurationService);
config.get('http.requestTimeout'); // Same result as aboe: 30000

Or you can get the whole configuration object of the http package:

config.get('http'); // Return the full "HttpConfigurationInterface" object

// Same as:
config.get(HttpConfigurationSymbol);

The symbol's description is used to get from http to the HttpConfigurationSymbol internally.

All packages' configurations have their kebab-casedopen in new window package name as description of their Symbol, so they can be accessed by string.

Here are all the possible ways of getting a configuration object or value:

config.get(HttpConfigurationSymbol)     // get the full "http" configuration
config.get('http')                      // same as above
config.get('http.timeout', 2000)        // get the "timeout" value of the "http" configuration with a default value of "2000" if not defined
config.get(['http', 'timeout'], 2000)   // same as above

WARNING

One important thing to note is that all objects returned by get() are cloned.

Meaning you can't keep a reference on the configuration object on your side and update it, it would not update the configuration object.

Updating

If you want to change a configuration value, you must do it through the modify() method:

import { HttpConfigurationInterface, HttpConfigurationSymbol } from "@banquette/http";

config.modify<HttpConfigurationInterface>(HttpConfigurationSymbol, {
    requestTimeout: 5000 // Here we override the timeout of the HTTP configuration
});

This enforces good practices and prevent from having multiple references on the configuration object in the app, making it hard to track where changes come from.

TIP

The generic type <HttpConfigurationInterface> is optional, but required if you want your IDE to autocomplete you with the available configuration values and to type check.

Registering

You can register your own configuration object if you want to. There are a few rules you have to comply with though:

  1. you must define an interface that extends the ConfigurationInterface from @banquette/config,
  2. you must define a Symbol that will be used to identify your configuration,
  3. if you want your configuration to be accessible by String, you must give it a unique description that will be used as key.

To register your object, use the register method:

export const CustomConfigurationSymbol = Symbol('custom');
config.register(CustomConfigurationSymbol, {
   param: 'value'
}, true);

The arguments are:

  1. the Symbol that identifies your configuration,
  2. the configuration object,
  3. an optional boolean indicating if the configuration should be available using the string notation (default is false).

TIP

The symbol's description becomes mandatory and must be unique if you want the object to be accessible by string.