Comments (7)
That would probably work. My opinion is that it would be nicer if it was done at the loadConfigOrThrow stage (as that means you could have a set of sources containing configuration and load a subset of the data from across all of them without duplicating the prefix every time you added the source), but if that is a much harder implementation, then setting it per file would also work.
It's basically useful if you want to extract some information out of someone else's config file without needing to write matching data classes for every single element. Instead you'd just write data classes for the bits you wanted and then provide the "path" to the start element if that makes any sense.
from hoplite.
Have a similar use case, migrating from Spring Boot where @ConfigurationProperties are bound by prefix.
This is really a separation of concerns - loading (once) of underlying properties (property sources, etc), and then - separately - binding properties to objects, based on a prefix.
In Spring the former is the "Environment" - all the resolved properties, with a PropertyResolver interface for consumers to access them; and way-overly-complex Binder objects that allow for something like this (my code, much more direct than the magical incantations of @ConfigurationProperties):
public inline fun <reified T : Any> Environment.bindConfigurationProperties(prefix: String): T {
return Binder.get(this).bindOrCreate(prefix, Bindable.of(T::class.java))
}
Ideally we'd be able to do something like:
val config = ConfigLoaderBuilder.default()
.addResourceSource("/application-staging.props", optional = true, allowEmpty = true)
.withExplicitSealedTypes()
.build()
// above exists today, sort of: ideally we could get a "Configuration" or "Environment" object back that can then be used as below (in addition to existing uses)
config.bind<MyConfigObject>(prefix = "abc") // this would have the same semantics as config.loadConfigOrThrow<MyConfigObject>(), except that the config would already be loaded
Selective binding supports a wide range of use cases - one of the more important ones is allowing different components to have their own configuration (and possibly multiple, separately configured instances), without coupling everything into a global config.
from hoplite.
So if you could specify the prefix when you add the file source, would be that sufficient ?
from hoplite.
I like the concept suggested by @tomhillgreyridge.
In addition (I'm not sure if this is part of the original suggestion), I would like to have the possibility to load "leaf" nodes, for example:
val plugin1Value2 = configLoader.loadConfigOrThrow<String>(prefix = "plugin1.value2")
I would also like to have the possibility to deal with nullable values, for example:
val plugin1Value2 = configLoader.loadConfigOrThrow<String?>(prefix = "plugin1.value2")
from hoplite.
Looking for this capability as well. I'm building a system (a simplified no-annotation Spring Boot) in which configurations are modular, and the possible prefixes are not known by the configuration system in advance.
from hoplite.
Just in case anybody wants it, I just built this in a project of mine:
class PrefixPreprocessor(val prefix: String) : Preprocessor {
override fun process(
node: Node,
context: DecoderContext,
): ConfigResult<Node> {
return node.atPath(prefix).valid()
}
}
To be used like this:
inline fun <reified T> loadConfig(prefix: String? = null): T {
val loader =
ConfigLoaderBuilder.default()
.addResourceSource("/config.yaml")
.also {
if (prefix != null) {
it.addPreprocessor(PrefixPreprocessor(prefix))
}
}
return loader.build().loadConfigOrThrow()
}
I won't find time to make this into a PR anytime soon, but maybe it helps others already like this (or someone else makes it into a PR) :-)
from hoplite.
// above exists today, sort of: ideally we could get a "Configuration" or "Environment" object back that can then be used as below (in addition to existing uses)
config.bind(prefix = "abc") // this would have the same semantics as config.loadConfigOrThrow(), except that the config would already be loaded
Selective binding supports a wide range of use cases - one of the more important ones is allowing different components to have their own configuration (and possibly multiple, separately configured instances), without coupling everything into a global config.
Agree with this from @cloudshiftchris . At the moment, if one uses a preprocessor approach like @lenalebt above (thank you!), things work as expected, but loading of the property sources happens multiple times. This also results in some suboptimal behavior like a report printing per prefix.
from hoplite.
Related Issues (20)
- NullPointerException on Config load HOT 3
- Log sources considered and used HOT 7
- YAML validation of string values for list-of-string types HOT 1
- Parameter mapping and cascading do not work together sometimes
- Code for unresolved substitution checking appears to be unused
- Environment variables in HOCON files will not be resolved in some cases
- .properties file HOT 2
- when using hoplite-hikaricp properties are not marked as "used"
- Support camelCase for allowUppercaseNames HOT 2
- Loading arrays from the Environment HOT 1
- Kotlin Multiplarform HOT 1
- Java 8 Support HOT 7
- How Do I Correctly Add A Preprocessor? HOT 1
- failure during substitution with custom user prompt
- Support idiomatic environment variable naming
- Add documentation to configuration paramters HOT 1
- Programmatic access to Configuration definition
- New Release? HOT 1
- GraalVM support
- Get Error in CI
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from hoplite.