Core components
Server core
Application configuration
26 min
overview the application configuration component is a foundational element of the ir engine's server core that manages the server's operational parameters and environment specific settings it provides a centralized system for defining, accessing, and updating configuration values that control various aspects of the server's behavior by abstracting configuration from code, this system enables the server to adapt to different deployment environments without requiring code changes this chapter explores the implementation, workflow, and benefits of the application configuration system within the ir engine core concepts environment variables environment variables serve as external inputs to the configuration system definition key value pairs provided to the application from its runtime environment sources can be loaded from env files, system environment, or deployment platforms isolation keeps sensitive information separate from the codebase flexibility allows different values in development, testing, and production environments security provides a way to manage secrets without committing them to version control these variables form the foundation of the configuration system structured configuration the system transforms raw environment variables into a structured configuration object organization groups related settings into logical categories type safety provides typescript interfaces for configuration objects default values defines fallbacks when environment variables are missing validation ensures required values are present and properly formatted documentation self documents the server's configuration requirements this structured approach makes configuration more maintainable and less error prone dynamic updates some configurations can be updated at runtime database stored settings configuration values stored in a database runtime modifications ability to change certain settings without restarting overrides database values can override environment variables centralized management enables configuration changes across multiple instances versioning tracks changes to configuration over time this dynamic capability enhances flexibility in production environments implementation configuration loading the configuration system loads values from environment variables // simplified from src/appconfig ts import dotenv from 'dotenv'; import path from 'path'; // load environment variables from env file dotenv config({ path path resolve(process cwd(), ' env local') }); // database configuration export const db = { username process env mysql user || 'defaultuser', password process env mysql password || '', database process env mysql database || 'irengine', host process env mysql host || 'localhost', port parseint(process env mysql port || '3306'), dialect 'mysql', url process env database url }; // server configuration export const server = { port parseint(process env server port || '3030'), hostname process env server host || 'localhost', publicdir process env public dir || path resolve(' /public/'), nodeenv process env node env || 'development', paginate { default parseint(process env paginate default || '10'), max parseint(process env paginate max || '100') } }; // authentication configuration export const authentication = { entity 'identity provider', service 'identity provider', secret process env auth secret || 'default secret change me', authstrategies \['jwt', 'local'], local { usernamefield 'email', passwordfield 'password' }, jwtoptions { expiresin process env jwt expires in || '1d' } }; // aws configuration export const aws = { s3 { accesskeyid process env aws access key id || '', secretaccesskey process env aws secret access key || '', region process env aws region || 'us east 1', s3forcepathstyle true, signatureversion 'v4' } }; // combine all configurations const config = { db, server, authentication, aws, // other configuration categories }; export default config; this code loads environment variables from a env local file defines structured configuration objects for different aspects of the system provides default values for missing environment variables combines all configuration categories into a single exported object configuration usage other parts of the application import and use the configuration // example of configuration usage in database setup import config from ' /appconfig'; import knex from 'knex'; // create database connection using configuration export const createknexclient = () => { return knex({ client 'mysql2', connection { host config db host, port config db port, user config db username, password config db password, database config db database }, pool { min 2, max 10 } }); }; this code imports the configuration object from appconfig ts uses database configuration values to create a database connection demonstrates how configuration is consumed by other components dynamic configuration updates the system can update configuration values from a database // simplified from src/updateappconfig ts import config from ' /appconfig'; import { createknexclient } from ' /db'; / updates application configuration with values from the database / export const updateappconfig = async () promise\<void> => { // create database client const knexclient = createknexclient(); try { // fetch settings from database const settings = await knexclient('engine settings') select('category', 'key', 'value') where('enabled', true); // update configuration with database values for (const setting of settings) { updatenestedconfig( config, setting category, setting key, setting value ); } console log('configuration updated from database settings'); } catch (error) { console error('failed to update configuration from database ', error); } finally { // close database connection await knexclient destroy(); } }; / updates a nested property in the configuration object / function updatenestedconfig( config any, category string, key string, value string ) void { // ensure category exists if (!config\[category]) { config\[category] = {}; } // update the value, converting to appropriate type if (value === 'true' || value === 'false') { config\[category]\[key] = value === 'true'; } else if (!isnan(number(value))) { config\[category]\[key] = number(value); } else { config\[category]\[key] = value; } } this code connects to the database using the initial configuration fetches settings from an engine settings table updates the configuration object with values from the database handles type conversion for boolean and numeric values configuration workflow the complete configuration workflow follows this sequence sequencediagram participant envfile as env file participant appconfig as src/appconfig ts participant config as configuration object participant updateconfig as src/updateappconfig ts participant database as settings database participant appcomponents as application components envfile >>appconfig load environment variables appconfig >>config create initial configuration alt dynamic updates enabled updateconfig >>database fetch settings database >>updateconfig return settings updateconfig >>config update configuration end config >>appcomponents provide configuration values note over appcomponents application uses configuration this diagram illustrates environment variables are loaded from env files the appconfig ts file creates the initial configuration object if dynamic updates are enabled, updateappconfig ts fetches settings from the database the configuration object is updated with database values application components use the configuration values configuration categories the configuration system includes several categories of settings database configuration settings for database connections // database configuration example export const db = { username process env mysql user || 'defaultuser', password process env mysql password || '', database process env mysql database || 'irengine', host process env mysql host || 'localhost', port parseint(process env mysql port || '3306'), dialect 'mysql', url process env database url }; these settings control database connection credentials database server location connection parameters database type and dialect server configuration settings for the server itself // server configuration example export const server = { port parseint(process env server port || '3030'), hostname process env server host || 'localhost', publicdir process env public dir || path resolve(' /public/'), nodeenv process env node env || 'development', paginate { default parseint(process env paginate default || '10'), max parseint(process env paginate max || '100') } }; these settings control network port and hostname public directory for static files environment mode (development, production) pagination defaults for api responses authentication configuration settings for user authentication // authentication configuration example export const authentication = { entity 'identity provider', service 'identity provider', secret process env auth secret || 'default secret change me', authstrategies \['jwt', 'local'], local { usernamefield 'email', passwordfield 'password' }, jwtoptions { expiresin process env jwt expires in || '1d' } }; these settings control authentication strategies jwt secret and expiration user entity and service field mappings for authentication storage configuration settings for file storage // storage configuration example export const storage = { provider process env storage provider || 'local', local { basedir process env storage local base dir || path resolve(' /uploads') }, s3 { bucket process env storage s3 bucket || 'irengine uploads', region process env aws region || 'us east 1', accesskeyid process env aws access key id || '', secretaccesskey process env aws secret access key || '' }, gcs { bucket process env storage gcs bucket || 'irengine uploads', keyfilename process env google application credentials || '' } }; these settings control storage provider selection local storage directory cloud storage credentials and buckets region and access settings integration with other components the configuration system integrates with several other components of the server core database management the configuration provides database connection details // example of database integration import config from ' /appconfig'; import knex from 'knex'; // create database connection const db = knex({ client 'mysql2', connection { host config db host, port config db port, user config db username, password config db password, database config db database } }); // export database client export default db; this integration uses database configuration to establish connections ensures consistent database access across the application allows database settings to be changed without code modifications authentication & authorization the configuration defines authentication strategies and settings // example of authentication integration import config from ' /appconfig'; import { authenticationservice } from '@feathersjs/authentication'; import { jwtstrategy } from '@feathersjs/authentication jwt'; import { localstrategy } from '@feathersjs/authentication local'; // configure authentication service export default function(app) { const authentication = new authenticationservice(app); // set up jwt strategy authentication register('jwt', new jwtstrategy({ secret config authentication secret, jwtoptions config authentication jwtoptions })); // set up local strategy authentication register('local', new localstrategy({ usernamefield config authentication local usernamefield, passwordfield config authentication local passwordfield })); // add authentication service app use('/authentication', authentication); } this integration configures authentication strategies based on configuration sets up jwt secrets and options defines username and password fields creates a flexible authentication system storage providers the configuration determines which storage provider to use // example of storage integration import config from ' /appconfig'; import { localstorage } from ' /storage/local'; import { s3storage } from ' /storage/s3'; import { gcsstorage } from ' /storage/gcs'; // create appropriate storage provider export function createstorageprovider() { switch (config storage provider) { case 's3' return new s3storage(config storage s3); case 'gcs' return new gcsstorage(config storage gcs); case 'local' default return new localstorage(config storage local); } } this integration selects the appropriate storage provider based on configuration initializes the provider with the correct settings enables switching between storage options without code changes provides a consistent interface regardless of the underlying provider benefits of application configuration the application configuration system provides several key advantages separation of concerns keeps configuration separate from code environment adaptability enables the server to run in different environments security keeps sensitive information out of the codebase centralization provides a single source of truth for configuration flexibility allows configuration changes without code modifications dynamic updates enables runtime configuration changes in some cases documentation self documents the server's configuration requirements these benefits make the application configuration system an essential foundation for the ir engine's server core next steps with an understanding of how the server is configured, the next chapter explores how these configurations are used to set up the main application framework next feathers application docid\ moirgwctqdikprjon3ujd