Configuration
View MarkdownVertique configuration is one merged tree with typed access and no required files:
- Zero files to start. No configuration file is required. Framework defaults apply and the application still starts.
- One merged tree. JSON and properties files, config stores, environment variables, system
properties, and the
--confoverlay combine in a fixed precedence order, and a higher source always wins. - Typed at the Dagger boundary. Your modules parse a section of the tree into a typed record
through
ConfigParserand do not read raw scalars. The parser’s coercion-lenient mapper is isolated from your API’s own JSON behavior. - Secrets never touch a file. A
${key}placeholder resolves at runtime against Vault, AWS Secrets Manager, AWS SSM Parameter Store, or Azure Key Vault, and no resolved value is written to disk. - Predictable resolution. A relative config directory resolves against the running process’s own working directory. This page covers the rule in detail because it is the most common first-run surprise.
This page explains where a generated Vertique application’s configuration comes from, how to consume it as a typed record inside your own Dagger modules, the order in which configuration sources combine, and how to route secrets into that tree without writing them into a file.
Where configuration lives in a generated application
Section titled “Where configuration lives in a generated application”The REST application generated in Quickstart ships one configuration file,
config/application.json, at the project root:
{ "http": { "port": 8080, "idleTimeoutSeconds": 60 }, "management": { "port": 9090, "enabled": true }}Vertique reads every *.json and *.properties file from each configured directory. The
directory is config/ by default, or the directories named by the VERTX_CONFIG_LOCATIONS
environment variable, a comma-separated list. Later directories override earlier ones, and within
one directory *.properties overrides *.json. No configuration file is required: when no
config/ directory exists next to the running process, framework defaults apply and the
application still starts. To override a default, edit config/application.json under the
application’s own working directory. For the quickstart application, that is
rest-app/config/application.json.
Each relative configured directory is resolved against the running process’s own current
working directory. It is not resolved against the compiled classpath. An absolute
VERTX_CONFIG_LOCATIONS entry is used as-is. Starting the generated application with
mvn -ntp exec:java from rest-app/ (as in Quickstart) therefore reads
rest-app/config/application.json. Starting the same application from another directory does
not, unless VERTX_CONFIG_LOCATIONS names the directory. A file under
src/main/resources/config/ is on the classpath only and is not read as startup configuration.
Typed configuration at the Dagger boundary
Section titled “Typed configuration at the Dagger boundary”Your own Dagger modules read configuration by injecting the framework’s ConfigParser and
parsing a section of the root @VertxConfig tree into a typed record. Do not call
JsonObject.mapTo or read a raw @Named scalar at the Dagger boundary:
@ProvidesHelloConfig helloConfig(@VertxConfig JsonObject config, ConfigParser parser) { return parser.parse(JsonConfigPaths.navigateObject(config, "hello"), HelloConfig.class);}ConfigParser is provided by ConfigParsingModule. Each of the three application starters
(vertique-starter-core, vertique-starter-rest, and vertique-starter-services) already
includes it transitively through CoreApplicationModule, so you do not list it again yourself
when building on one of them. A capability starter such as vertique-starter-postgresql supplies
no config parser on its own. See Application model for the full starter
table and which starters must be paired with an application starter. The parser uses an isolated,
coercion-lenient object mapper independent of the mapper your REST layer uses for request and
response bodies, so a config-parsing decision does not leak into your API’s JSON behavior.
Resilience configuration
Section titled “Resilience configuration”Resilience policy is configured at the consumer boundary. REST and Services use the canonical
annotations from dev.vertique.resilience.annotation for timeout, retry, circuit-breaker, and
bulkhead declarations. A concrete bean uses @Resilient as the method-level anchor; a service
contract or REST-client interface can use the declaration annotations directly. Typed JSON
configuration can override those declarations for an environment, but configuration alone does
not activate resilience for an operation without an annotation or anchor.
maxRetries is bounded from 0 through 100, and timeout fields use explicit units such as
timeoutMs or timeoutSeconds according to the owning module’s reference. Retry policy must match
the operation’s replay and idempotency guarantees. Framework adapters do not expose bulkhead
configuration in this release, although programmatic pipelines in vertique-resilience can use a
bulkhead explicitly.
Name a resilience policy tier
Section titled “Name a resilience policy tier”Use @Resilient(policy = "payments") when several operations should share an environment-specific
policy. The tier lives under resilience.policies and contains only the concerns it overrides:
{ "resilience": { "policies": { "payments": { "retry": { "maxRetries": 5, "delayMs": 100, "maxDelayMs": 1000 } } } }}The annotation selects the tier and does not copy configuration into source code. Resolution uses
operation and transport overrides first, then the named tier, then declaration values and family
defaults. A named tier can supply the whole active policy when the anchor has no inline declaration.
An unknown tier is a startup error, and a tier that defines no resilience concern is invalid. The
full record shape and supported bounds are in the vertique-resilience module reference.
Fatal JVM Error values are rethrown. They are not retried or counted as ordinary failures. The
runtime accepts one consequence of Vert.x cleanup: fatal cleanup can reset accumulated closed-state
breaker failures and close a half-open breaker before the same fatal value is rethrown.
Configuration source precedence
Section titled “Configuration source precedence”Vertique merges configuration from several sources into one tree, in this order from lowest to highest precedence:
*.jsonfiles in each config directory*.propertiesfiles in each config directory- Declared
config.storesentries - Environment variables
- System properties
- The
--confoverlay (highest precedence; always wins)
A value declared in a higher-precedence source always overrides the same key supplied by a lower one.
Secret providers
Section titled “Secret providers”Vertique publishes four secret providers. Three resolve secrets as property sources: your
application’s own configuration declares a ${key} placeholder reference, and the property source
resolves it against declared entries under config.propertySources. The fourth, AWS SSM Parameter
Store, is a config.stores entry that eagerly merges a whole parameter subtree directly into the
config tree (see Configuration source precedence above).
| Provider | Artifact | Model |
|---|---|---|
| HashiCorp Vault (KV v2) | vertique-config-vault |
Eager property source. Every declared path is read once at bootstrap |
| AWS Secrets Manager | vertique-config-aws-secrets |
Eager property source. Every declared secret is fetched once at bootstrap |
| AWS SSM Parameter Store | vertique-config-aws-ssm |
Config store, not a property source. It merges a whole parameter subtree into the tree |
| Azure Key Vault | vertique-config-azure-keyvault |
On-demand property source. Only keys referenced by a placeholder are fetched |
Each of the three property-source providers supports the same self-reference idiom for pulling a secret into the tree without writing its value into any file: declare the placeholder under its own key, and the recursive tree probe falls through to the declared source instead of looping.
{ "db": { "password": "${db.password}" }, "config": { "propertySources": [ { "name": "vault-app", "type": "vault", "address": "http://vault:8200", "paths": [{ "path": "secret/app", "prefix": "db." }] } ] }}Learn more
Section titled “Learn more”vertique-coremodule reference: theConfigParserseam, the@VertxConfigqualifier, andJsonConfigPaths.vertique-config-coremodule reference: the full precedence chain,config.stores, and the placeholder resolution engine.vertique-config-vaultmodule referencevertique-config-aws-secretsmodule referencevertique-config-aws-ssmmodule referencevertique-config-azure-keyvaultmodule reference- Application model
- What is Vertique?
Continue reading
Section titled “Continue reading”- Previous: Dependency injection
- Next: JSON and profiles