GithubHelp home page GithubHelp logo

Comments (7)

tomhillgreyridge avatar tomhillgreyridge commented on July 17, 2024 3

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.

cloudshiftchris avatar cloudshiftchris commented on July 17, 2024 2

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.

sksamuel avatar sksamuel commented on July 17, 2024

So if you could specify the prefix when you add the file source, would be that sufficient ?

from hoplite.

jogro avatar jogro commented on July 17, 2024

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.

rocketraman avatar rocketraman commented on July 17, 2024

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.

lenalebt avatar lenalebt commented on July 17, 2024

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.

rocketraman avatar rocketraman commented on July 17, 2024

// 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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.