github.com/tickoalcantara12/micro/v3@v3.0.0-20221007104245-9d75b9bcbab9/docs/blog/_posts/2018-07-04-go-config.md (about)

     1  ---
     2  layout:	post
     3  title:	Go Config - A pluggable config framework
     4  date:	2018-07-04 09:00:00
     5  ---
     6  <br>
     7  Application configuration has remained largely static for most of our lifetime, using flags, environment variables and files. 
     8  Any change has usually required restarting the application or significant complexity in code to signal and reload the config. 
     9  
    10  Today though, we need more. Restarting an application for a minor configuration seems like overkill. If only one property 
    11  needs to change, should there not be a better way? Dynamic configuration provides us this option. 
    12  
    13  ### Dynamic Config
    14  
    15  Dynamic configuration is the concept by which a system can be modified or extended while it's running. Or in simpler terms 
    16  the values you require for configuration are automatically updated as they change.
    17  
    18  There's an emergence of tooling for dynamic config mostly driven by key-value stores as the source of truth. Yet when we then 
    19  need to extract out these values it requires reading individual keys, extracting bytes and handling decoding manually.
    20  
    21  In an ideal world, the configuration system should handle all of these concerns leaving you to focus on what's most important. 
    22  Your code.
    23  
    24  [**Go Config**](https://github.com/micro/go-config) is a pluggable config framework which looks to solve these problems.
    25  
    26  ### Go Config
    27  
    28  Go Config was born out of a need to simplify configuration for users of micro. Once companies had started building real 
    29  products that were going to production they echoed the need for the ability to provide configuration for business logic 
    30  related code or higher level config that shouldn't really necessitate the need for a restart.
    31  
    32  In some cases they had opted for the kubernetes config map or a key-value store such as consul or etcd but handling 
    33  this configuration in code was not pleasant. They were looking for abstractions similar to Go Micro for their config.
    34  
    35  And so Go Config was created to help with this and much more.
    36  
    37  Go Config is:
    38  
    39  - **Dynamic** - Config is updated transparently in the background
    40  - **Pluggable** - Backend sources can be swapped out
    41  - **Mergeable** - Multiple sources are merged into a single source of truth
    42  - **Observable** - Actively watch the config for changes if you need
    43  - **Safe** - Default fallback values can be specified in case they don't exist
    44  
    45  
    46  It also has the benefit of supporting multiple backend sources and config encoding formats out of the box. See the project 
    47  [readme](https://github.com/micro/go-config) for details.
    48  
    49  Here's the top level interface which encapsulates all the features mentioned.
    50  
    51  <script src="https://gist.github.com/asim/9365ffa1115d2215a39d9073a2fa0ffc.js"></script>
    52  
    53  Ok so let's break it down and discuss the various concerns in the framework starting with the backend sources.
    54  
    55  ### Source
    56  
    57  A source is a backend from which config is loaded. This could be command line flags, environment variables, a key-value store 
    58  or any other number of places.
    59  
    60  Go Config provides a simple abstraction over all these sources as a simple interface from which we read data or what we call a ChangeSet.
    61  
    62  <script src="https://gist.github.com/asim/45a0c1f0a40c29c034b1aea796a24c96.js"></script>
    63  
    64  The ChangeSet includes the raw data, it's format, timestamp of creation or last update and the source from which it was loaded. 
    65  There's also an optional md5 checksum which can be recalculated using the `Sum()` method.
    66  
    67  The simplicity of this interface allows us to easily create a source for any backend, read it's values at any given time or 
    68  watch for changes where possible.
    69  
    70  ### Encoding
    71  
    72  Config is rarely available in just a single format and people usually have varying preferences on whether it should be stored 
    73  in json, yaml, toml or something else. We make sure to deal with this in the framework so almost any encoding format can be 
    74  dealt with.
    75  
    76  The encoder is a very simply interface for handling encoding and decoding different formats. Why wouldn't we reuse existing libraries for 
    77  this? We do beneath the covers but to ensure we could deal with encoding in an abstract way it made sense to define an interface for it.
    78  
    79  <script src="https://gist.github.com/asim/131349521cbb974c680cd3a245bf13c7.js"></script>
    80  
    81  The current supported formats are json, yaml, toml, xml and hcl.
    82  
    83  ### Reader
    84  
    85  Once we've loaded backend sources and developed a way to decode the variety of config formats we need some way of actually internally 
    86  representing and reading it. For this we've created a reader.
    87  
    88  The reader manages decoding and merging multiple changesets into a single source of truth. It then provides a value interface which 
    89  allows you to retrieve native Go types or scan the config into a type of your choosing.
    90  
    91  <script src="https://gist.github.com/asim/e19799834382975b85e1c1813c4e2f89.js"></script>
    92  
    93  Our default internal representation for the merged source is json.
    94  
    95  ### Example
    96  
    97  Let's look at how Go Config actually works in code. Starting with a simple example, let's read config from a file. 
    98  
    99  #### Read Config
   100  
   101  Step 1. Define a config.json file
   102  
   103  <script src="https://gist.github.com/asim/f6ddc55133f54f32fe0e9e6813e286dc.js"></script>
   104  
   105  Step 2. Load the file into config
   106  
   107  <script src="https://gist.github.com/asim/716a352d1f2d071fbf14a4fae39fc692.js"></script>
   108  
   109  
   110  Step 3. Read the values from config
   111  
   112  <script src="https://gist.github.com/asim/d97fe7bd2d16b125c721808e693ba88b.js"></script>
   113  
   114  And that's it! It's really that simple.
   115  
   116  #### Watch Config
   117  
   118  If the config file changes, the next time you read the value it will be different. But what if you want to 
   119  track that change? You can watch for changes. Let's test it out.
   120  
   121  <script src="https://gist.github.com/asim/d7b98889aaf0342f99c0360641907bc0.js"></script>
   122  
   123  In this example rather than getting a value, we watch it. The next time the value changes we'll receive it and 
   124  can update our Host struct.
   125  
   126  #### Merge Config
   127  
   128  Another useful feature is the ability to load config from multiple sources which are ordered, merged and overridden.
   129  A good example of this would be loading config from a file but overriding via environment variables or flags.
   130  
   131  <script src="https://gist.github.com/asim/e91071c4eaff6e0a081ea43a9cdcf7da.js"></script>
   132  
   133  #### Fallback Values
   134  
   135  In the event some values may not exist or config does not load due to an error, you can set fallback values at 
   136  time of getting them.
   137  
   138  <script src="https://gist.github.com/asim/fbfef8fcfe16cb252377fae821c03a2e.js"></script>
   139  
   140  ### Summary 
   141  
   142  The way in which config is managed and consumed needs to evolve. Go Config looks to do this by drastically simplifying 
   143  use of dynamic configuration with a pluggable framework. 
   144  
   145  Go Config currently supports a number of configuration formats and backend sources but we're always looking for 
   146  more contributions. If you're interested in contribution please feel free to do so by with a pull request.
   147  
   148  Let Go Config managed the complexity of configuration for you so you can focus on what's really important. Your code.
   149  
   150  To learn more about micro check out the [website](https://m3o.com), follow us on [twitter](https://twitter.com/m3ocloud) or 
   151  join the [slack](https://slack.m3o.com) community.
   152  
   153  <h6><a href="https://github.com/micro/go-config"><i class="fab fa-github fa-2x"></i> Go Config</a></h6>