Skip to main content

Configuration

Almost nothing about your API should be hard-coded: which database to connect to, which port to listen on, what secret key to sign tokens with. These things change between your laptop, your test environment, and production, and some of them (like secrets) shouldn't be written directly into your source code at all. Configuration is where all of that lives instead, in one place your code reads from, rather than scattered if statements checking where it's running.

RapidREST doesn't invent its own configuration system. It uses a well-established one called nconf, set up for you in src/config.ts when your project is generated.

The one thing that trips people up

nconf organizes settings into a tree, and separates each level with a colon (:), not a dot. config.get("auth.secret") will quietly return undefined. The correct form is config.get("auth:secret"). This is worth remembering now, since it'll look wrong to anyone used to JavaScript's usual dot notation.

What a config file looks like

// src/config.ts
import nconf from 'nconf';

const conf = nconf
.argv()
.env({separator: '__', parseValues: true});

conf.defaults({
service_name: 'my-api',
auth: {
strategy: 'auth.JWTStrategy',
secret: 'change-me-in-production',
options: {
expiresIn: '1 hour',
audience: 'my-api.example.com',
issuer: 'api.example.com',
},
},
class_loader: {
ignore: [/server\..*/, /config\..*/],
},
cors: {origins: ['http://localhost:3000']},
datastores: {
mongo: {type: 'mongodb', host: 'localhost', database: 'my_api'},
},
logger: {level: 'info'},
rbac: {enabled: true},
trusted_roles: ['admin'],
});

export default conf;

Everything inside conf.defaults({...}) is a default, the value used if nothing else overrides it. That's deliberate: it means your generated project runs out of the box with sane values, while still leaving every one of those values changeable without touching code.

Overriding a default without editing code

Because .env() is set up with separator: '__', any of these nested keys can be overridden by setting an environment variable, using a double underscore everywhere the key has a colon. For example, to change the JWT secret without editing config.ts:

AUTH__SECRET=a-real-production-secret rapidrest start

This is exactly how you're expected to hand over real secrets and real database connection strings once you deploy somewhere: you don't put production secrets in a file that gets committed to source control, you set them as environment variables on whatever server or container is actually running your code.

Reading a config value in your own code

Anywhere you already have a reference to the config object:

config.get('datastores');
config.get('rbac:enabled');
config.get('auth:options:expiresIn');

Inside a class that RapidREST already manages for you (a route, a model, a service, see Dependency Injection), you don't need to import the config object at all. Ask for the value with @Config instead, and it'll already be filled in by the time your code runs:

@Config('trusted_roles', ['admin'])
protected trustedRoles: string[] = ['admin'];

The second argument here (['admin']) is a fallback used only if that key doesn't exist in your configuration at all, separate from the conf.defaults() values, which is a per-property safety net rather than the primary way to set defaults.

The keys you'll see most often

Almost every other page in these docs eventually points back to one of these:

KeyWhat it controls
datastoresYour database connections, one entry per named database (see Models & Persistence)
authWhich login strategy is used by default, and the secret/options for signing tokens (see Auth)
rbac:enabledTurns the permissions system on or off, globally
trusted_rolesRoles that skip permission checks entirely
class_loader:ignoreWhich files Auto-Discovery should skip
port / listen_host / ssl / max_body_sizeWhat address your server listens on, and TLS settings (see HTTP Engine)
sessionServer-side session settings (see Sessions)
corsWhich other websites are allowed to call your API from a browser (see Cookies & CORS)
headersExtra headers added to every response your server sends
logger:levelHow much detail gets written to your logs