-
Notifications
You must be signed in to change notification settings - Fork 6
Schemas
NestJSConfigManager is essentially a schema-first configuration module. This means that in most use-cases, the configuration process revolves around a schema. A schema is a set of rules that govern:
- Which environment variables are required
- For required environment variables, a set of
Joi
schema rules for validating user-supplied values - For optional environment variables, a default value
As described in the Quick Start, you define your schema
in a sub-class derived from the ConfigManager
class. In that derived class,
you implement a required method called provideConfigSpec()
. This method takes
an optional parameter, environment
, containing the value of the current
environment, and returns a schema.
A schema is a simple JSON object made up of one key per environment variable
that you wish to validate, with each key having a value made up of a simple
object with two or three keys. In other words, an entry for the required
environment variable DB_HOST
would look like:
DB_HOST: {
validate: Joi.string(),
required: true,
}
Where validate
must be a valid
joi schema,
and required
is a boolean.
If required
is false
(the default, so you may omit it), you must provide
a default value using the default
key. In other words, all fields in the schema
will be ensured of resolving to a valid value -- either provided by the environment, or provided as a default.
For example, specify an optional field like this:
DB_PORT: {
validate: Joi.number()
.min(5000)
.max(65535),
required: false,
default: 5432,
}
A complete schema, and the surrounding provideConfigSpec()
method, might
look like the following. Here we omit required: false
on fields that are optional
and have a default value. This style is recommended as it reads a little bit
more naturally.
provideConfigSpec() {
return {
DB_HOST: {
validate: Joi.string(),
required: true,
},
DB_USER: {
validate: Joi.string(),
required: true,
},
DB_PORT: {
validate: Joi.number()
.min(5000)
.max(65535),
default: 5432,
},
FIRST_NAME: {
validate: Joi.string(),
required: true,
}
PORT: {
validate: Joi.number()
.min(3000)
.max(500),
default: 3000,
},
};
}
Your provideConfigSpec()
method is called with an environment
parameter of
type string
which is equal to the value of the current environment. In other
words, if you're running in development, provideConfigSpec()
receives a
parameter environment
with the value 'development'
. This is available in
case you want to conditionally enforce different schema validations for different
environments.
For example, the following code will ensure that your production environment
will use a minimum value of 12
for SALT_ROUNDS
:
provideConfigSpec(enviroment) {
const MIN_SALT_ROUNDS = environment === 'production' ? 12 : 8;
return {
SALT_ROUNDS: {
validate: Joi.number().min(MIN_SALT_ROUNDS),
default: MIN_SALT_ROUNDS,
}
}
In the How it works section we discussed how basic environment cascades work. The NestJSConfigManager builds on this using schemas to:
- Add extra variables from the
.env
file (if they're allowed) - Apply default values for env vars that are missing
- Validate the results
The following diagram shows the entire process. The light blue box (bottom center) shows the series of steps performed by the NestJSConfigManager.
