Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[V2] Have a better configuration system #805

Closed
LoicPoullain opened this issue Aug 28, 2020 · 1 comment
Closed

[V2] Have a better configuration system #805

LoicPoullain opened this issue Aug 28, 2020 · 1 comment

Comments

@LoicPoullain
Copy link
Member

LoicPoullain commented Aug 28, 2020

Issue

There had been many feedbacks on the framework configuration (#743, #735, #497, #788, #428, #803, Discord). Current system is not great and does not meet all the needs as it should be.

What can be improved

  • The link between the environment variable XXX_YYY_ZZZ and Config.get('xxx.yyy.zzz') (or Config.get('xxx.yyyZzz')) is confusing and not intuitive.
  • It is not possible to access directly an environment variable defined in a .env file (unlike the library dotenv).
  • Some components of the framework require specific environment variable names (ex: REDIS_URI, MONGODB_URI) which is annoying when the PaaS we have use different names.
  • It is not possible to add comments or use quotes in the .env.
  • It is not possible to specify JWT RSA public/private keys from .pem files.
  • It it is not possible to divide very large config files in sub-files and sub-directories.

What should be kept

  • Be able to specify configuration in YAML and JSON files.
  • Have a unified way in the framework to access the configuration values (especially for the framework std components).
  • Be able to play with different environments.
  • Do not override the process.env.{variable} to avoid unexpected errors in 3p libraries and to be able to use other types than the string one.

Solutions

Add these changes/improvements to the configuration system.

1. Support JS files

In addition to YAML and JSON formats, the framework will support .js files.

2. Have access to .env variables and the environment variables in config files

In YAML:

settings:
  jwt:
    secret: 'env(SECRET_VARIABLE_NAME)'

In JSON:

{
  "settings": {
    "jwt": {
      "secret": "env(SECRET_VARIABLE_NAME)"
    }
  }
}

In JS:

const { Env } = require('@foal/core');

module.exports = {
  settings: {
    jwt: {
      secret: Env.get('SECRET_VARIABLE_NAME')
    }
  }
}

3. Remove the links between XXX_YYY_ZZZ and Config.get('xxx.yyy.zzz')

The link must be set explicitly in the config file:

settings:
  jwt:
    secret: 'env(SETTINGS_JWT_SECRET)'

4. Support comments and quotes in .env files

Example of pretty printed errors in v2

ConfigNotFound

\n\n
  -------------------------------------------------------- 
|                                                          |
|  JSON file (config/default.json, config/test.json, ...)  |
|                                                          |
| -------------------------------------------------------- |
|                                                          |
|  {                                                       |
|    "settings": {                                         |
|      "session": {                                        |
|        "store": <your_value>                             |
|        // OR with an environment variable:               |
|        "store": "env(<YOUR_ENVIRONMENT_VARIABLE>)"       |
|      }                                                   |
|    }                                                     |
|  }                                                       |
|                                                          |
  --------------------------------------------------------

  -------------------------------------------------------- 
|                                                          |
|  YAML file (config/default.yml, config/test.yml, ...)    |
|                                                          |
| -------------------------------------------------------- |
|                                                          |
|  settings:                                               |
|    session:                                              |
|      store: <your_value>                                 |
|      # OR with an environment variable:                  |
|      store: 'env(<YOUR_ENVIRONMENT_VARIABLE)>'           |       
|                                                          |
  --------------------------------------------------------

  -------------------------------------------------------- 
|                                                          |
|  JS file (config/default.js, config/test.js, ...)        |
|                                                          |
| -------------------------------------------------------- |
|                                                          |
|  const { Env } = require('@foal/core');                  |
|                                                          |
|  {                                                       |
|    settings: {                                           |
|      session: {                                          |
|        store: <your_value>                               |
|        // OR with an environment variable:               |
|        store: Env.get('<YOUR_ENVIRONMENT_VARIABLE>')     |
|      }                                                   |
|    }                                                     |
|  }                                                       |
|                                                          |
  --------------------------------------------------------

No value found for the configuration key « settings.session.store ».

Custom message.

To pass a value, use one of the examples above.
\n\n

ConfigTypeError

  -------------------------------------------------------- 
|                                                          |
|  Configuration file                                      |
|                                                          |
| -------------------------------------------------------- |
|                                                          |
|  {                                                       |
|    settings: {                                           |
|      session: {                                          |
->       store: *************                              |
|      }                                                   |
|    }                                                     |
|  }                                                       |
|                                                          |
  --------------------------------------------------------

The value of the configuration key "${key}" has an invalid type.

Expected a "${expected}", but got a "${actual}".

Comparison with other frameworks (refenrences)

https://guides.rubyonrails.org/configuring.html
https://symfony.com/doc/current/configuration.html
https://docs.djangoproject.com/en/3.0/topics/settings/
https://adonisjs.com/docs/4.0/configuration-and-env
https://laravel.com/docs/7.x/configuration

@LoicPoullain
Copy link
Member Author

Resolved in v2

Issue tracking automation moved this from Work In Progress to Done / Closed This Release Sep 4, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Issue tracking
  
Done / Closed This Release
Development

No branches or pull requests

1 participant