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.
SSMPropertySource
SecretsManagerPropertySource
EnvironmentPropertySource
CommandLinePropertySource
JsonPropertySource
YamlPropertySource
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;
// ...
}
}