Tutorial: Configuration

Configuration

It's important to get your configuration settings right when using Flitter. Flitter behaves differently in development mode than it does running in production -- this includes exposing error messages and stack traces that could reveal sensitive information about your application. In this section, we'll take a look at how Flitter handles configuration, and the best way to customize it.

Flitter Config: A Two-Layer Approach

Configuration in Flitter is loaded in two steps. Environment-specific config is done by changing values in a .env file in the root of the application. This file is never, ever committed to version control and should not be published with your app. It includes things like the database credentials, crypto key, and environment settings.

Flitter ships with a sample example.env file that you can customize. Just cp example.env .env and fill in your information. It's important that you replace the SECRET variable with a random value, as it's used by Flitter to encrypt things like password hashes. Here's a sample:

APP_NAME=Flitter
APP_URL=http://localhost:8000/

SERVER_PORT=8000
LOGGING_LEVEL=1

DATABASE_HOST=127.0.0.1
DATABASE_PORT=27017
DATABASE_NAME=flitter
DATABASE_AUTH=false

SECRET=changeme
ENVIRONMENT=production

SSL_ENABLE=false
SSL_CERT_FILE=cert.pem
SSL_CERT_KEY=cert.key

All other configuration is defined in .config.js files in the config/ folder. Here's a sample server.config.js:

const server_config = {
    port: env("SERVER_PORT", 80),
    environment: env("ENVIRONMENT", "production"),

    logging: {
        level: env("LOGGING_LEVEL", 1)
    },

    session: {
        secret: env("SECRET", "changeme")
    },

    uploads: {
        destination: './uploads'
    },

    ssl: {
        enable: (env("SSL_ENABLE") ? (env("SSL_ENABLE") === 'true') : false),
        cert_file: env("SSL_CERT_FILE", 'cert.pem'),
        key_file: env("SSL_KEY_FILE", 'cert.key'),
    },
}

module.exports = server_config

The env() function is a special function that is only available within the .config.js files. It refers to environment variables defined in the .env file we discussed above. The first argument corresponds to the name of the variable, and the second (optional) argument corresponds to the default value, in case the variable isn't defined.

When the framework starts, these configuration files are loaded and stored in memory based on the name of the file. Then, you can access them globally using the configs service (more on that later). Note that the name of the file defines the name of the configuration, not the actual variable name. This is true of most things with Flitter. Here's an example:

Note that the sample configuration file was called server.config.js, so we access the configuration called server.

(flitter)> _services.configs.get('server')

// returns:
{ port: 80,
  environment: 'production',
  logging: { level: 1 },
  session: { secret: 'changeme' } }

(flitter)> _services.configs.get('server.port')

// returns:
80

(That bit there was the Flitter shell, if you were curious. It allows you to interact with Flitter directly. You can get to it by running ./flitter shell.)

Flitter takes into account sub-directories when naming configuration as well. Say you had a configuration file config/auth/registration.config.js. Flitter would note the auth/ sub-directory, and you would access this configuration using _services.configs.get('auth:registration').

The use of the : character is an important Flitter convention. Flitter parses reference names from file paths relative to their base directory. When referencing folders, use the : character to separate them. For instance, auth/login/error becomes auth:login:error. Internally, this is referred to as a "Flitter canonical name." The canonical naming scheme is a powerful way of accessing shared resources throughout the application.

Creating Custom Configuration Files

You can add custom configuration files to your application, and they will be loaded by Flitter and made available globally like any other configuration file. To create a new config file, you can use ./flitter, Flitter's development CLI tool, to create a new configuration file from the built-in template:

./flitter new config subdirectory:file_name

This will generate the following file, config/subdirectory/file_name.config.js:

// file_name Configuration
const file_name = {

    // variable: env('VARIABLE', 'default value'),

}

module.exports = file_name

Now you can specify the configuration values you want, then the configuration can be referenced from _services.configs.get('subdirectory:file_name').

Next: Routing