Skip to content

App config

AppConfig is the one object you give to Dox().initialize(). It lives in lib/config/app.dart. This page lists every field, with its type, its default and what it does.

Source: packages/dox-core/lib/interfaces/app_config.dart.

Server

Field Type Default Meaning
appKey String required Encrypts cookies (req.cookie(), DoxCookie) and signs local storage URLs. In production the app stops at start when it is empty. Make one with dox key:generate.
serverPort int 3000 The port the HTTP server listens on. When the env has no APP_PORT but has PORT, Dox listens on PORT instead (Cloud Run, Fly, Render and Heroku set it).
host String? null: APP_HOST, else all interfaces The network interface to listen on, like 127.0.0.1. null reads the env var APP_HOST. With neither, Dox listens on all interfaces, IPv6 and IPv4 (::).
totalIsolate int? Platform.numberOfProcessors Isolates (threads) that serve HTTP, all on the same port. On Windows the native server runs on one isolate.
server ServerBackend ServerBackend.native Which HTTP server runs: native (Rust, dox_http_native) or dartIo. The env var DOX_SERVER wins over this value. See Native server.
compress bool false gzip responses in Dart (HttpServer.autoCompress). It costs CPU on every response. Let a proxy do it when you have one.
maxBodySize int 10 * 1024 * 1024 (10 MB) Biggest JSON or urlencoded body in bytes. Bigger gets 413.
maxMultipartSize int 100 * 1024 * 1024 (100 MB) Biggest multipart/form-data body (file uploads) in bytes. Bigger gets 413.
shutdownTimeout Duration Duration(seconds: 8) On SIGTERM or SIGINT, how long open requests may run before Dox closes them. Keep it below the kill timeout of your platform. See Graceful shutdown.
trustedProxies List<String> [] IPs or CIDR ranges of reverse proxies. Only when the direct client is in this list does Dox read X-Forwarded-For for req.ip() and X-Forwarded-Proto for req.scheme(). ['*'] trusts any client.

Routing and request handling

Field Type Default Meaning
routers List<Router> [] The router classes that register routes.
globalMiddleware List<dynamic> [] Middleware that runs on every route. A function or an IDoxMiddleware.
dtos List<DtoSchema<Object>> [] Every DTO of the app: dtos from lib/dtos.g.dart. Dox finds the DTO of a controller parameter and of req.validate<T>() with it.
validationMessages MessageResolver? null (English messages) Messages for validation errors, for example in other languages.
responseHandler ResponseHandlerInterface? null A class with DoxResponse handle(DoxResponse res). It sees every response before it is sent.
errorHandler Function(Object?, StackTrace) defaultErrorHandler Called for every unhandled error. The default logs the error with Logger.warn and the stack with Logger.danger.
services List<DoxService> [] Classes with a setup() method. Dox runs them in every isolate at start. The ORM, auth and WebSocket are set up here.

Sub configs

Field Type Default Meaning
cors CORSConfig CORSConfig() CORS headers. See CORSConfig.
logger LoggerConfig LoggerConfig() The Logger output. See LoggerConfig.
cache CacheConfig file store in storage/cache, plus a memory store Cache stores for Cache(). See CacheConfig.
storage StorageConfig local disk with root storage Storage disks for Storage(). See StorageConfig.
openApi OpenApiConfig OpenApiConfig() /docs, /openapi.json and /openapi.yaml. See OpenApiConfig.
socketIo SocketIoConfig SocketIoConfig() (off) Socket.IO on the HTTP port. See SocketIoConfig.

CORSConfig

Source: packages/dox-core/lib/interfaces/app_config.dart. Headers are set in packages/dox-core/lib/http/http_cors_handler.dart.

A value can be a String ('*' or a comma list) or a List<String>. A null value sends no header.

Field Type Default Header
enabled bool true Send CORS headers. A route can override it with its own cors setting.
origin dynamic null Access-Control-Allow-Origin. One origin, '*', or a list. With a list, Dox sends back only the request origin if it is in the list.
methods dynamic null Access-Control-Allow-Methods
headers dynamic null Access-Control-Allow-Headers
exposeHeaders dynamic null Access-Control-Expose-Headers
credentials bool? null Access-Control-Allow-Credentials
maxAge num? null Access-Control-Max-Age in seconds

Note

With the default CORSConfig() every value is null. So enabled: true alone sends no header. Set origin at least.

LoggerConfig

Field Type Default Meaning
name String '' The name field in each JSON log line.
enabled bool false Turn the Logger on.
prettyPrint bool false true prints colored text. false prints one JSON object per line (for log services).
level String 'info' The lowest level to print: debug, info, warn or error. Logger.success counts as info. Logger.danger counts as error. An unknown value prints every line.

CacheConfig

Source: packages/dox-cache/lib/src/cache_config.dart. Option keys: packages/dox-cache/lib/src/constants/cache_constants.dart.

Field Type Default Meaning
defaultStore String required The store Cache() uses when no store is named.
stores Map<String, Map<String, dynamic>> required Store name to options. Each store needs a driver option.

Options of each driver:

Driver Option Type Default Meaning
all driver String required file, memory, redis or null
all prefix String dox_cache: Text in front of every key.
file path String storage/cache Folder of the cache files.
memory max_size int no limit Most items in the map.
redis host String 127.0.0.1 Redis host.
redis port int 6379 Redis port.
redis username String none Redis user.
redis password String none Redis password.
redis db int 0 Redis database number.
redis tls bool false Use TLS.
redis pool_size int 10 Most connections per store.

StorageConfig

Source: packages/dox-core/lib/storage/storage_config.dart.

Field Type Default Meaning
defaultDisk String 'local' The disk Storage() uses when no disk is named.
disks Map<String, Map<String, dynamic>> {'local': {'driver': 'local', 'root': 'storage'}} Disk name to options. Each disk needs a driver option.

Options of each driver:

Driver Option Type Default Meaning
all driver String required local, s3 or memory
local root String storage Folder of the files.
local url String none Base of the public URLs, like http://localhost:3000/files.
local app_key String AppConfig.appKey Key that signs the URLs.
local visibility String public public or private.
s3 bucket String required Bucket name.
s3 region String us-east-1 Region.
s3 key String required Access key id.
s3 secret String required Secret access key.
s3 token String none Session token.
s3 endpoint String none Custom endpoint (R2, MinIO, Spaces).
s3 path_style bool false Use path style URLs.
s3 url String none Base of the public URLs.
s3 visibility String private public or private.
s3 acl bool true The service supports ACLs.
s3 batch_delete bool true The service supports batch delete.

An unknown driver throws ArgumentError('Storage disk "<name>" has unknown driver "<type>"').

OpenApiConfig

Source: packages/dox-core/lib/openapi/openapi_config.dart.

Field Type Default Meaning
enabled bool? null Serve the docs routes. null means: on only when APP_ENV is development or local.
info Info Info(title: 'Dox API', version: '1.0.0') Title and version of the API.
servers List<Server> [] Base URLs of the API.
securitySchemes Map<String, SecurityScheme> {} Ways to log in, like {'bearerAuth': SecurityScheme.bearer()}.
securityByMiddleware Map<String, List<Map<String, List<String>>>> {} Security for routes that use a middleware class with this name. AuthMiddleware gets bearerAuth when it is not in the map.
registry OpenApiRegistry OpenApiRegistry() (empty) What dox_builder found in the code. Pass openApiRegistry from lib/openapi.g.dart.
ui DocsUi DocsUi.scalar scalar or swagger.
scalar ScalarOptions ScalarOptions() Options of the Scalar page. See below.
pageTitle String? null (uses info.title) Title of the /docs page.

ScalarOptions (packages/dox-openapi/lib/src/docs_ui.dart):

Field Type Default Meaning
theme ScalarTheme ScalarTheme.default_ One of default_, alternate, moon, purple, solarized, bluePlanet, deepSpace, saturn, kepler, elysiajs, fastify, mars, laserwave, none.
darkMode bool false Start in dark mode.
showDownloadButton bool true Show the download button for the OpenAPI document.
proxyUrl String? null Send "Try it" requests through this proxy.

SocketIoConfig

Source: packages/dox-core/lib/socketio/socket_io_config.dart.

Field Type Default Meaning
enabled bool false Mount Socket.IO on the HTTP port at /socket.io/.
options ServerOptions ServerOptions() Engine options. See below.
namespaces List<NamespaceHandler> [] Namespaces to register, like ChatNamespace().
adapter SocketAdapterFactory? null (in memory) Makes the adapter in each isolate. Use a Redis adapter with many isolates.

ServerOptions (packages/dox-socketio/lib/src/engine/server_options.dart). The defaults match the Node.js server.

Field Type Default Meaning
path String /socket.io/ URL path. Must end with /.
pingInterval Duration 25 s Time between two server pings.
pingTimeout Duration 20 s Time to wait for a pong before the session is closed.
upgradeTimeout Duration 10 s Time a websocket upgrade may take.
connectTimeout Duration 45 s Time a client has to join a namespace after the handshake.
maxHttpBufferSize int 1000000 Biggest message in bytes a client may send.
transports List<String> ['polling', 'websocket'] Allowed transports.
allowUpgrades bool true Allow upgrades from polling to websocket.
cors CorsOptions? null (no CORS headers) CORS for the long-polling requests.

CorsOptions:

Field Type Default Meaning
origins List<String> ['*'] Allowed origins.
credentials bool false Send Access-Control-Allow-Credentials: true.
methods List<String> ['GET', 'POST'] Allowed methods for preflight.
allowedHeaders List<String>? null (the requested headers) Allowed request headers.
maxAge Duration? null How long a browser may cache the preflight answer.

DatabaseConfig

The database is not a field of AppConfig. A service calls SqlQueryBuilder.initializeWithDatabaseConfig(databaseConfig) in its setup(). Source: packages/dox-orm/lib/src/types/database_config.dart and connection_config.dart.

Field Type Default Meaning
connection String required Name of the connection to use. A missing name throws Exception('<name> not found').
connections Map<String, ConnectionConfig> required Connection name to config.

ConnectionConfig:

Field Type Default Meaning
driver Driver required Driver.postgres, Driver.mysql (also MariaDB) or Driver.sqlite.
host String 'localhost' Database host. Not used by sqlite.
port int 0 Database port. Not used by sqlite.
user String '' Database user. Not used by sqlite.
password String '' Database password. Not used by sqlite.
database String required Database name. For sqlite: the file path, or :memory:.
useSSL bool false Use TLS. Postgres with TLS uses the Dart driver, not the native one.
debug bool required Print every query with printer.
printer QueryPrinter? null ConsoleQueryPrinter(), PrettyQueryPrinter(), FileQueryPrinter() or your own.
extra Map<String, dynamic> {} Driver options. See below.
driverFactory DBDriver Function(ConnectionConfig)? null Your own driver class. It wins over every other setting.

Keys of extra:

Driver Key Type Default Meaning
postgres, mysql native bool true false uses the Dart driver instead of the native (Rust) one.
postgres, mysql maxConnectionCount int 10 Most open connections.
postgres, mysql preparedStatementCacheSize int 100 Prepared statements kept per connection.
postgres sslMode postgres SslMode none Setting it uses the Dart driver.
mysql collation String utf8mb4_general_ci Connection collation.
mysql timeoutMs int 10000 Connect timeout.
mysql allowPublicKeyRetrieval bool true Ask the server for its RSA key (needed for caching_sha2_password without TLS).
mysql serverPublicKey String none The server RSA key, so it is not asked for.
mysql timeZone String none Session time zone.
mysql maxConnectionAge Duration 12 hours Close and reopen a connection after this time.
sqlite busyTimeout int 5000 PRAGMA busy_timeout in milliseconds.

AuthConfig

Auth is not a field of AppConfig. A service calls Auth.initialize(AuthConfig(...)) in its setup(). Source: packages/dox-auth/lib/src/interfaces.dart.

Class Field Type Default Meaning
AuthConfig defaultGuard String required The guard Auth() uses when no guard is named.
AuthConfig guards Map<String, AuthGuard> {} Guard name to guard.
AuthGuard driver AuthDriver required How a token is made and checked, like JwtAuthDriver(secret: SecretKey(...)).
AuthGuard provider AuthProvider required Where users come from.
AuthProvider model dynamic Function() required Makes the user model, like () => User().
AuthProvider identifierFields List<String> ['email'] Columns attempt() matches the login with.
AuthProvider passwordField String 'password' Column with the bcrypt hash.

Full example

This is the lib/config/app.dart of a new project. The sub configs live in their own files in lib/config/.

lib/config/app.dart
import 'dart:io';

import 'package:dox_core/dox_core.dart';
import 'package:my_app/app/http/response_handler.dart';
import 'package:my_app/config/cache.dart';
import 'package:my_app/config/cors.dart';
import 'package:my_app/config/logger.dart';
import 'package:my_app/config/services.dart';
import 'package:my_app/config/storage.dart';
import 'package:my_app/routes/api.dart';
import 'package:my_app/routes/web.dart';
import 'package:my_app/config/env.dart';

AppConfig appConfig = AppConfig(
  /// Application secret key
  /// -------------------------------
  /// This key is use to encrypt/decrypt the data such as cache and cookies.
  /// Make sure to keep the `APP_KEY` as an environment variable and secure.
  ///
  /// Note: Changing the application key for an existing app will make all
  /// the cookies and cache invalid and also the existing encrypted data
  /// will not be decrypted.
  appKey: env.appKey,

  /// Server port
  /// -------------------------------
  /// App will be running on this port.
  serverPort: env.appPort,

  /// Total isolate (multi thread)
  /// -------------------------------
  /// Isolates that serve http requests, all on the same port.
  /// Default is one per CPU core, so the app uses all cores.
  /// Set `APP_TOTAL_ISOLATE` to change it.
  totalIsolate: env.appTotalIsolate ?? Platform.numberOfProcessors,

  /// Global middleware
  /// -------------------------------
  /// By registering global middleware here,
  /// middleware will be applied to all the routes.
  globalMiddleware: <dynamic>[LogMiddleware(enabled: true)],

  /// Routers
  /// -------------------------------
  /// Register routers to create route to dox framework.
  routers: <Router>[WebRouter(), ApiRouter()],

  /// Response handler
  responseHandler: ResponseHandler(),

  /// Cache stores (config/cache.dart)
  cache: cache,

  /// Storage disks (config/storage.dart)
  storage: storage,

  /// Cors configuration
  cors: cors,

  /// Service to run on multithread server
  services: services,

  /// logger configuration
  logger: logger,
);

The config files read their values from env, the typed env class in lib/config/env.dart. See Env reference.

The sub config files, with the values a new project ships:

lib/config/cache.dart
import 'package:dox_core/dox_core.dart';
import 'package:my_app/config/env.dart';

/// Cache stores
/// -------------------------------
/// `Cache()` uses the default store. `Cache().store('memory')` picks one.
/// Drivers: file, memory, redis, null. Values must be JSON types.
CacheConfig cache = CacheConfig(
  defaultStore: env.cacheStore,
  stores: <String, Map<String, dynamic>>{
    'file': <String, dynamic>{'driver': 'file', 'path': 'storage/cache'},

    /// one map per isolate, fast, not shared
    'memory': <String, dynamic>{'driver': 'memory', 'max_size': 10000},
  },
);
lib/config/storage.dart
import 'package:dox_core/dox_core.dart';
import 'package:my_app/config/env.dart';

/// Storage disks
/// -------------------------------
/// `Storage()` uses the default disk. `Storage().disk('local')` picks one.
/// Drivers: local, s3 (also R2, MinIO, Spaces), memory.
StorageConfig storage = StorageConfig(
  defaultDisk: env.storageDisk,
  disks: <String, Map<String, dynamic>>{
    /// files in the `storage` folder
    'local': <String, dynamic>{'driver': 'local', 'root': 'storage'},
  },
);
lib/config/logger.dart
import 'package:dox_core/dox_core.dart';
import 'package:my_app/config/env.dart';

LoggerConfig logger = LoggerConfig(
  /// Application name
  /// -------------------------------
  /// The name of the application you want to add to the log.
  name: env.appName,

  /// Toggle logger
  /// -------------------------------
  /// Enable or disable logger in application.
  enabled: true,

  /// Logging level
  /// -------------------------------
  /// The level from which you want the logger to flush logs.
  level: env.logLevel,

  /// Pretty print
  /// -------------------------------
  /// It is highly advised NOT to use `prettyPrint` in production, since it
  /// can have huge impact on performance.
  prettyPrint: env.isDevelopment,
);
lib/config/database.dart
import 'package:dox_orm/dox_orm.dart';
import 'package:my_app/config/env.dart';

/// Print every SQL query only in development.
/// Printing each query costs time, so it is off in production.
bool _debug = env.isDevelopment;

DatabaseConfig databaseConfig = DatabaseConfig(
  /// Connection
  /// -------------------------------
  /// The connection to use. It is one key of `connections` below.
  connection: env.dbConnection,

  connections: <String, ConnectionConfig>{
    /// Postgres
    'postgres': ConnectionConfig(
      driver: Driver.postgres,
      host: env.dbHost,
      port: env.dbPort ?? 5432,
      user: env.dbUsername,
      password: env.dbPassword,
      database: env.dbName,
      extra: <String, dynamic>{
        /// Each isolate has its own pool.
        'maxConnectionCount': 10,
        'maxConnectionAge': Duration(hours: 1),
      },
      debug: _debug,
      printer: PrettyQueryPrinter(),
    ),

    /// MySQL and MariaDB
    'mysql': ConnectionConfig(
      driver: Driver.mysql,
      host: env.dbHost,
      port: env.dbPort ?? 3306,
      user: env.dbUsername,
      password: env.dbPassword,
      database: env.dbName,
      extra: <String, dynamic>{'collation': 'utf8mb4_general_ci'},
      debug: _debug,
      printer: PrettyQueryPrinter(),
    ),

    /// SQLite. `DB_NAME` is a file path, or `:memory:`.
    'sqlite': ConnectionConfig(
      driver: Driver.sqlite,
      database: env.dbName,
      debug: _debug,
      printer: PrettyQueryPrinter(),
    ),
  },
);
lib/config/cors.dart
import 'package:dox_core/dox_core.dart';

CORSConfig cors = CORSConfig(
  /// Enabled
  /// -------------------------------
  /// A boolean to enable or disable CORS integration.
  /// Setting to true will enable the CORS for all HTTP request.
  enabled: false,

  /// Origin
  /// -------------------------------
  /// Set the origins to be allowed for `Access-Control-Allow-Origin`.
  /// The value can be one of the following:
  /// List        : Allowed origins. Dox sends back only the request origin
  ///               when it is in the list.
  /// String      : One allowed origin.
  /// String (*)  : A wildcard (*) to allow all request origins.
  origin: '*',

  /// Methods
  /// -------------------------------
  /// Set a list of origins to be allowed for `Access-Control-Request-Method`.
  /// The value can be one of the following:
  /// Array       : An array of request methods.
  /// String      : Comma separated list of request methods.
  /// String (*)  : A wildcard (*) to allow all request methods.
  methods: '*',

  /// Headers
  /// -------------------------------
  /// Set a list of origins to be allowed for `Access-Control-Allow-Headers`.
  /// The value can be one of the following:
  /// Array       : An array of allowed headers.
  /// String      : Comma separated list of allowed headers.
  /// String (*)  : A wildcard (*) to allow all request headers.
  headers: '*',

  /// Expose Headers
  /// -------------------------------
  /// Set a list of origins to be allowed for `Access-Control-Expose-Headers`.
  /// The value can be one of the following:
  /// Array       : An array of expose headers.
  /// String      : Comma separated list of expose headers.
  exposeHeaders: <String>[
    'cache-control',
    'content-language',
    'content-type',
    'expires',
    'last-modified',
    'pragma',
  ],

  /// Credentials
  /// -------------------------------
  /// Toggle `Access-Control-Allow-Credentials` header.
  credentials: true,

  /// MaxAge
  /// -------------------------------
  /// Define `Access-Control-Max-Age` header in seconds.
  maxAge: 90,
);
lib/config/services.dart
import 'package:dox_core/dox_core.dart';
import 'package:my_app/services/orm_service.dart';

/// Services to register on dox
/// -------------------------------
/// Since dox run on multi thread isolate, we need to register
/// below extra services to dox so that dox can
/// register again on new isolate.
List<DoxService> services = <DoxService>[ORMService()];
lib/services/orm_service.dart
import 'package:dox_core/dox_core.dart';
import 'package:dox_orm/dox_orm.dart';
import 'package:my_app/config/database.dart';

/// Query builder service
/// --------------------------
/// Sets up the query builder, so this project can use the ORM.
/// If this project does not need a database, delete this file
/// and remove it from config/services.dart.
class ORMService implements DoxService {
  @override
  Future<void> setup() async {
    SqlQueryBuilder.initializeWithDatabaseConfig(databaseConfig);
  }
}

A new project has no openapi.dart, socketio.dart or auth service. You add them when you need them. See OpenAPI, Socket.IO and Authentication.