Configuration

Configuration is the settings that change from one place to another while the code stays the same: a server URL, a port, a timeout, a feature switch.

Why

The same build runs on a laptop, in tests and in production. Each place needs its own values, and nothing should be recompiled for that. So the settings live outside the code: in config files, on the command line, in environment variables and in --dart-define values.

The keys, file names and rules are Spring Boot's. Configuration from a Spring project usually works unchanged.

The annotations and the Environment are part of spring_core_dart. Reading the config files at startup and binding @ConfigurationProperties classes is done by SpringApplication (spring_boot_dart and the starters built on it). A plain ApplicationContext.run reads only the environment variables, unless you load the files yourself with ConfigDataEnvironment.

How it fits together

Example

# lib/resources/application.yml
shop:
  title: NEON Books
  url: ${SHOP_URL:http://localhost:8080}
  max-basket-size: 20
  checkout-timeout: 30s
---
spring:
  config:
    activate:
      on-profile: prod
shop:
  url: https://neon.books
import 'package:spring_core_dart/spring_core_dart.dart';

// A whole prefix as a typed bean.
@ConfigurationProperties('shop')
class ShopProperties {
  String title = 'Shop';
  String url = '';
  int maxBasketSize = 10;
  Duration checkoutTimeout = const Duration(minutes: 1);
}

@Service()
class Checkout {
  Checkout(
    this.shop,
    // One value; a raw string, so Dart does not read `$`.
    @Value(r'${shop.title}') this.title,
  );

  final ShopProperties shop;
  final String title;
}
dart run bin/main.dart --spring.profiles.active=prod --shop.max-basket-size=30

Pages of this section

In Spring (Java)

This is Spring Boot's Externalized Configuration. Differences that matter:

The full reference, with every key the framework reads, is configuration.md on GitHub.

See also