Configuration files
A configuration is read by the person who adjusts it and by the program that loads it. With a template, an error is caught in the editor and not in production.
A service's configuration
Server Config (com.acme.server):
Name: api-gateway
Environment: production
Network:
Host: 0.0.0.0
Port: 8080
Public url: https://api.acme.com
# The 5000 ms limit comes from the SLA with the payments provider
Timeouts:
Read ms: 5000
Write ms: 5000
Logging:
Level: INFO
Format: json
Features:
Feature: experimental-cache
Enabled: false
Feature: audit-logging
Enabled: true
Notes >>
Main configuration of the API gateway. Versioned with the application and
deployed with it.
Changes to Network and Timeouts go through Reliability review.In this example we have:
- Groups:
Network,Timeouts,LoggingandFeatures. They are nodes without a value, which group their children. - Settings:
Host,Port,Level... They are nodes with a value. - Feature flags: the value of the
Featurenode is the name, and its childEnabledis the state. - Explanations: a comment for a short note, or a block node such as
Notesfor a long text. The difference is thatNotesis part of the document, and a program can display it.
The template
Template (@stxt.template): com.acme.server
Structure >>
Server Config:
Name: (1)
Environment: (1) ENUM [dev, staging, production]
Network: (1)
Host: (1)
Port: (1) NATURAL
Public url: (?) URL
Timeouts: (?)
Read ms: (?) NATURAL
Write ms: (?) NATURAL
Logging: (?)
Level: (1) ENUM [DEBUG, INFO, WARN, ERROR]
Format: (?) ENUM [text, json]
Features: (?)
Feature: (*)
Enabled: (1) BOOLEAN
Notes: (?) TEXTA configuration that does not validate
Many configuration loaders ignore a misspelled key and apply the default value. With the template, these errors stop being silent:
# ERROR: this document does not validate
Server Config (com.acme.server):
Name: api-gateway
Environment: production
Network:
Host: 0.0.0.0
# `Ports` does not exist, it is `Port`
Ports: 8080
Logging:
# Lowercase `info` is not `INFO`
Level: info
Features:
Feature: audit-logging
# A BOOLEAN is `true` or `false`
Enabled: yesAnd this is what stxt validate answers:
/home/ana/gateway/config/server.stxt:8: [NODE_NOT_DEFINED_IN_SCHEMA] NOT EXIST NODE ports for namespace com.acme.server (error)
/home/ana/gateway/config/server.stxt:8: [CHILD_NOT_DECLARED] Child 'com.acme.server:ports' not declared in node 'com.acme.server:network' (error)
/home/ana/gateway/config/server.stxt:5: [TOO_FEW_CHILDREN] 0 nodes of 'com.acme.server:port' and min is 1 (error)
/home/ana/gateway/config/server.stxt:11: [INVALID_VALUE] The value 'info' is not one of the allowed values of Level (error)
/home/ana/gateway/config/server.stxt:15: [INVALID_VALUE] Enabled: Invalid boolean (yes) (error)
5 error(s), 0 warning(s)
The VS Code extension marks the same errors while typing. In continuous integration,
stxt validate --recursive config/ stops the deployment of an invalid configuration
(The command line).
Several environments, one structure
A single document can have one node per environment, and the template guarantees that all of them declare the same things:
Application Config (com.acme.app):
App name: Billing
Environments:
Environment: dev
Database:
Url: jdbc:postgresql://localhost/dev
Max connections: 5
Debug: true
Environment: staging
Database:
Url: jdbc:postgresql://staging/db
Max connections: 10
Debug: false
Environment: production
Database:
Url: jdbc:postgresql://prod/db
Max connections: 30
Debug: falseAnd its template:
Template (@stxt.template): com.acme.app
Structure >>
Application Config:
App name: (1)
Environments: (1)
Environment: (+)
Database: (1)
Url: (1)
Max connections: (1) NATURAL
Debug: (1) BOOLEANAn environment missing Database does not validate. If one file per environment is preferred,
the document is split in three with the same namespace and the same template.
How the program reads it
The program receives an already validated tree. It walks the nodes by their canonical
name (port, max-connections) and converts the values. The
TypeScript, Java and Python guides show how.
The template is looked up in the .stxt/ directories
(STXT-DISCOVERY-SPEC), the same as in the editor. That way, the editor and the program
apply the same definition.
Limits
In STXT a value is the text that is written. There are no:
- Variables or references to other values
- Inclusion of other files
- Expressions
- Default values in the template: if an optional node is missing, the program decides its value
It is a design decision: a configuration file cannot execute anything or depend on another. If a base file has to be composed with one per environment, the application does it on load.
To compare with other configuration formats, see STXT vs YAML, which includes TOML, and STXT vs JSON.