A PropertySource is an interface that allows a configuration value to be loaded by its name. An implementation may either be sync or async depending on its backing implmentation.
interface PropertySource {
get(key: string): unknown;
}
interface AsyncPropertySource {
get(key: string): Promise<unknown>;
}There can also be a CompositePropertySource that is created from multiple sources and
aggregates all of its sources.
class CompositePropertySource implements AsyncPropertySource {
static from(...sources: (PropertySource | AsyncPropertySource)[]): CompositePropertySource
}A number of predefined property source implementations can be published and developers will have the ability to create their own as needed.
SSMPropertySourceSecretsManagerPropertySourceEnvironmentPropertySourceCommandLinePropertySourceJsonPropertySourceYamlPropertySource
Property names should be normalized when requested. This will allow values from environment variables
FOO_BAR and ssm foo/bar to be used interchangeably without concern to their implementation.
// the below forms are all equivalent
source.get('app.aws.accessKey');
source.get('app_aws_accesskey');
source.get('APP_AWS_ACCESSKEY');As configuration values should be accessed in a typesafe manner and validated upfront, a mechanism should be provided to bind property sources to a validated object that in turn can be injected.
This can be done as a class and/or functional approach.
@ConfigurationProperties({prefix: 'app.aws')
class GatewayProperties {
@NotEmpty()
accessKey: string;
}const gatewayProperties = configurationSchema({
prefix: 'app.aws',
properties: {
accessKey: string().notEmpty()
},
});
## Usage
The typesafe configuration objects can then be injected into services.
```ts
class AwsGateway {
constructor(private @Inject(GatewayProperties) properties) {
}
assumeRole() {
const accessKey = this.properties.accessKey;
// ...
}
}