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 calledserver
.
(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
becomesauth: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