diff --git a/docs/index.md b/docs/index.md index 266662d86..9643f4ceb 100644 --- a/docs/index.md +++ b/docs/index.md @@ -57,5 +57,5 @@ libraryDependencies += "dev.zio" %% "zio-config-magnolia" % "" // for d ```scala mdoc:passthrough import utils._ -printSource("examples/shared/src/main/scala/zio/config/examples/YamlConfigReaderExample.scala") +printSource("examples/shared/src/main/scala/zio/config/examples/configsources/YamlConfigReaderExample.scala") ``` diff --git a/docs/read-from-various-sources.md b/docs/read-from-various-sources.md index a45f65bcf..ebcdfc6a0 100644 --- a/docs/read-from-various-sources.md +++ b/docs/read-from-various-sources.md @@ -3,141 +3,134 @@ id: read-from-various-sources title: "Read from various Sources" --- -zio-config supports various sources. +ZIO Config supports various sources for reading configurations. In this guide, we will see how to read configurations from different sources such as in-memory maps, HOCON strings, files, YAML, and XML. -```scala mdoc:silent -import zio._, Config._, ConfigProvider._ -import zio.config._, magnolia._ -``` +## In-memory Map Source -```scala mdoc:silent -case class MyConfig(ldap: String, port: Int, dburl: String) +To load configs from an in-memory map, you can use `ConfigProvider.fromMap` method: + +```scala mdoc:passthrough +import utils._ +printSource("examples/shared/src/main/scala/zio/config/examples/configsources/InmemoryMapSourceExample.scala") ``` -```scala mdoc:silent -val myConfig = - (string("LDAP") zip int("PORT") zip string("DB_URL")).to[MyConfig] +## Typesafe (HOCON) Config Source - // val automatedConfig = deriveConfig[MyConfig]; using zio-config-magnolia -``` +To enable HOCON source, we have to add the `zio-config-typesafe` module to our dependencies in `build.sbt` file: +```scala +libraryDependencies += "dev.zio" %% "zio-config-typesafe" % "@VERSION@" +``` -## HOCON String +By importing the `zio.config.typesafe._` module, we can read configs from HOCON sources. -To enable HOCON source, you have to bring in `zio-config-typesafe` module. -There are many examples in examples module in zio-config. +### HOCON String -Here is an quick example +We can use `ConfigProvider.fromHoconString` to load configs from a HOCON string: -```scala mdoc:silent -import zio.config.typesafe._ -import zio.config.magnolia._ +```scala mdoc:passthrough +import utils._ +printSource("examples/shared/src/main/scala/zio/config/examples/configsources/TypesafeHoconStringSourceExample.scala") ``` -```scala mdoc:silent -case class SimpleConfig(port: Int, url: String, region: Option[String]) +### HOCON File -val automaticDescription = deriveConfig[SimpleConfig] +Similar to the above example, we can read configs from a HOCON file, using `ConfigProvider.fromHoconFile`. -val hoconSource = - ConfigProvider.fromHoconString( - """ - { - port : 123 - url : bla - region: useast - } - """ - ) +Assume we have a HOCON file `application.simple.conf` in the `resources` directory: -val anotherHoconSource = - ConfigProvider.fromHoconString( - """ - port=123 - url=bla - region=useast - """ - ) +```scala mdoc:passthrough +import utils._ +printSource("examples/shared/src/main/resources/application.simple.conf") +``` -hoconSource.load(deriveConfig[SimpleConfig]) +We can read the configuration file as follows: -// yielding SimpleConfig(123,bla,Some(useast)) +```scala mdoc:passthrough +import utils._ +printSource("examples/shared/src/main/scala/zio/config/examples/configsources/TypesafeHoconFileSourceExample.scala") ``` -## HOCON File +### JSON File + +We can use `zio-config-typesafe` module to fetch json as well. So let's add it to our `build.sbt` file: -```scala mdoc:silent -ConfigProvider.fromHoconFile(new java.io.File("fileapth")) +```scala +libraryDependencies += "dev.zio" %% "zio-config-typesafe" % "@VERSION@" ``` -## Json +Assume we have a JSON file `application.json` in the `resources` directory: -You can use `zio-config-typesafe` module to fetch json as well +```scala mdoc:passthrough +import utils._ +printSource("examples/shared/src/main/resources/application.json") +``` -```scala mdoc:silent -val jsonString = - """ - { - "port" : "123" - "url" : "bla" - "region": "useast" - } - """ +We can read the configuration file as follows: -ConfigProvider.fromHoconString(jsonString) +```scala mdoc:passthrough +import utils._ +printSource("examples/shared/src/main/scala/zio/config/examples/configsources/TypesafeJsonFileSourceExample.scala") ``` -## Yaml FIle +## YAML Source -Similar to Hocon source, we have `ConfigProvider.fromYamlString` +Let's add these four lines to our `build.sbt` file as we are using these modules in our examples: ```scala -import zio.config.yaml._ +libraryDependencies += "dev.zio" %% "zio-config" % "" +libraryDependencies += "dev.zio" %% "zio-config-yaml" % "" // for reading yaml configuration files +libraryDependencies += "dev.zio" %% "zio-config-magnolia" % "" // for deriving configuration descriptions +``` + +Assume we have the following configuration file: -ConfigProvider.fromYamlString +```scala +import utils._ +printSource("examples/shared/src/main/resources/application.yml") ``` -## Xml String +We can read the configuration file as follows: -zio-config can read XML strings. Note that it's experimental with a dead simple native xml parser, -Currently it cannot XML comments, and has not been tested with complex data types, which will be fixed in the near future. +```scala mdoc:passthrough +import utils._ +printSource("examples/shared/src/main/scala/zio/config/examples/configsources/YamlConfigReaderExample.scala") +``` -```scala -import zio.config.xml.experimental._ -import zio.Config +Here is the output: -final case class Configuration(aws: Aws, database: Database) +``` +bootstrapServers: List(localhost:9092, locathost:9094) +region: US +port: 100 +``` -object Configuration { - val config: Config[Configuration] = - Aws.config.nested("aws").zip(Database.config.nested("database")).to[Configuration].nested("config") +## XML - final case class Aws(region: String, account: String) +ZIO Config can read XML strings using the `zio-config-yaml` module, so we have to add the following line to our `build.sbt` file: - object Aws { - val config: Config[Aws] = Config.string("region").zip(Config.string("account")).to[Aws] - } - final case class Database(port: Int, url: String) +```scala +libraryDependencies += "dev.zio" %% "zio-config-yaml" % "@VERSION@" +``` - object Database { - val config: Config[Database] = Config.int("port").zip(Config.string("url")).to[Database] - } -} +Note that it's experimental with a dead simple native xml parser, +Currently it cannot XML comments, and has not been tested with complex data types, which will be fixed in the near future. -val config = - s""" - | - | - | - | - | - |""".stripMargin +Assume we have the `application.xml` file in the `resources` directory: -val parsed = ConfigProvider.fromYamlString(config).load(Configuration.config) +```scala mdoc:passthrough +import utils._ +printSource("examples/shared/src/main/resources/application.xml") ``` +We can load the configuration file as follows: + +```scala mdoc:passthrough +import utils._ +printSource("examples/shared/src/main/scala/zio/config/examples/configsources/YamlConfigReaderExample.scala") +``` -### Indexed Map, Array datatype, and a some implementation notes +## Indexed Map, Array datatype, and a some implementation notes `zio-config` comes up with the idea of `IndexedFlat` allowing you to define indexed configs (see examples below). However, the constructors of `IndexedFlat` is not exposed to the user for the time being, since it can conflate with some ideas in `zio.core` `Flat`, @@ -149,14 +142,15 @@ See https://github.com/zio/zio/pull/7823 and https://github.com/zio/zio/pull/789 These changes are to keep the backward compatibility of ZIO library itself. -#### What does it mean to users? +### What does it mean to users? It implies, for sequence (or list) datatypes, you can use either `` or `""` to represent empty list in a flat structure. See the below example where it tries to mix indexing into flat structure. We recommend using `` over `""` whenever you are trying to represent a real indexed format Example: -```scala +```scala mdoc:compile-only +import zio._ import zio.config._, magnolia._ final case class Department(name: String, block: Int) @@ -175,17 +169,17 @@ val map = "employees[1].departments" -> "", ) -ConfigProvider.fromMap(map).load(derivedConfig[Config]) +ConfigProvider.fromMap(map).load(deriveConfig[Config]) ``` Although we support indexing within Flat, formats such as Json/HOCON/XML is far better to work with indexing, and zio-config supports these formats making use of the above idea. -#### Another simple example of an indexed format - -```scala +### Another simple example of an indexed format +```scala mdoc:compile-only +import zio._ import zio.config._, magnolia._ final case class Employee(age: Int, name: String) diff --git a/examples/shared/src/main/resources/application.json b/examples/shared/src/main/resources/application.json new file mode 100644 index 000000000..99d542036 --- /dev/null +++ b/examples/shared/src/main/resources/application.json @@ -0,0 +1,5 @@ +{ + "port": "123", + "url": "bla", + "region": "useast" +} diff --git a/examples/shared/src/main/resources/application.simple.conf b/examples/shared/src/main/resources/application.simple.conf new file mode 100644 index 000000000..860ce3945 --- /dev/null +++ b/examples/shared/src/main/resources/application.simple.conf @@ -0,0 +1,3 @@ +port=123 +url=bla +region=useast diff --git a/examples/shared/src/main/resources/application.xml b/examples/shared/src/main/resources/application.xml new file mode 100644 index 000000000..728f98593 --- /dev/null +++ b/examples/shared/src/main/resources/application.xml @@ -0,0 +1,4 @@ + + + +