github.com/System-Glitch/goyave/v2@v2.10.3-0.20200819142921-51011e75d504/docs_src/src/guide/configuration.md (about)

     1  ---
     2  meta:
     3    - name: "og:title"
     4      content: "Configuration - Goyave"
     5    - name: "twitter:title"
     6      content: "Configuration - Goyave"
     7    - name: "title"
     8      content: "Configuration - Goyave"
     9  ---
    10  
    11  # Configuration
    12  
    13  [[toc]]
    14  
    15  ## Introduction
    16  
    17  
    18  The Goyave framework lets you configure its core and your application.
    19  To configure your application, use the `config.json` file at your project's root. If you are using the template project, copy `config.example.json` to `config.json`. `config.json` should be ignored in your `.gitignore` file as it can differ from one developer to another. To avoid accidental commit or change to the default project's config, it is a good practice to ignore this file and define the project's default config in `config.example.json`.
    20  
    21  If this config file misses some config entries, the default values will be used. Refer to the [configuration reference](#configuration-reference) to know more. 
    22  
    23  All entries are **validated**. That means that the application will not start if you provided an invalid value in your config (for example if the specified port is not a number). That also means that a goroutine trying to change a config entry with the incorrect type will panic.  
    24  Entries can be registered with a default value, their type and authorized values from any package. 
    25  
    26  Configuration can be used concurrently safely.
    27  
    28  The following JSON file is an example of default configuration:
    29  
    30  ```json
    31  {
    32    "app": {
    33      "name": "goyave_template",
    34      "environment": "localhost",
    35      "debug": true,
    36      "defaultLanguage": "en-US"
    37    },
    38    "server": {
    39      "host": "127.0.0.1",
    40      "maintenance": false,
    41      "protocol": "http",
    42      "domain": "",
    43      "port": 8080,
    44      "httpsPort": 8081,
    45      "timeout": 10,
    46      "maxUploadSize": 10,
    47      "tls": {
    48        "cert": "/path/to/cert",
    49        "key": "/path/to/key"
    50      },
    51    },
    52    "database": {
    53      "connection": "mysql",
    54      "host": "127.0.0.1",
    55      "port": 3306,
    56      "name": "goyave",
    57      "username": "root",
    58      "password": "root",
    59      "options": "charset=utf8&parseTime=true&loc=Local",
    60      "maxOpenConnections": 20,
    61      "maxIdleConnections": 20,
    62      "maxLifetime": 300,
    63      "autoMigrate": false
    64    }
    65  }
    66  ```
    67  
    68  ## Terminology
    69  
    70  **Entry**: a configuration entry is a value accessible using a key.
    71  
    72  **Registering an entry**: informs the framework that an entry with the given key is expected. Registering an entry allows to set a default value to be used if this entry is not provided in an app's configuration file, to enforce a certain type for this entry (for example if it needs to be an integer), and to set a list of allowed values.
    73  
    74  **Category**: a category is represented by a JSON object in your configuration file, delimited by braces. Sub-categories are categories that are not at root level, for example: `server.tls` is a sub-category of the `server` category.
    75  
    76  ## Environment configuration
    77  
    78  Most projects need different configuration values based on the environment. For example, you won't connect to the same database if you're in local development, in a testing environment inside continuous integration pipelines, or in production. Goyave supports multiple configurations and will pick the appropriate one depending on the environment variable `GOYAVE_ENV`.
    79  
    80  Since `v2.0.0`, you can use custom environments.
    81  
    82  | GOYAVE_ENV                    | Config file              |
    83  |-------------------------------|--------------------------|
    84  | test                          | `config.test.json`       |
    85  | production                    | `config.production.json` |
    86  | *custom_env*                  | `config.custom_env.json` |
    87  | local / localhost / *not set* | `config.json`            |
    88  
    89  ## Using the configuration
    90  
    91  Before being able to use the config, import the config package:
    92  ``` go
    93  import "github.com/System-Glitch/goyave/v2/config"
    94  ```
    95  
    96  The configuration is loaded automatically when the server starts, but you can reload it manually if needed.
    97  
    98  When the configuration is loaded, all default values are copied to the newly created map holding the configuration. Then, the configuration file is read, parsed and is applied over. This means that all entries from the file override the default ones. However, if an entry has a default value and the same entry is not present in the configuration file, then it is kept as it is. On the other hand, if an entry is present in the configuration file and not in the default values (meaning that this entry is not expected), a new entry will be registered.This new entry will be subsequently validated using the type of its initial value and have an empty slice as authorized values (meaning it can have any value of its type)
    99  
   100  The following cases will raise errors when the configuration is being overridden:
   101  - When the configuration file overrides an entry with a category
   102  - When the configuration file overrides a category with an entry
   103  
   104  #### config.Load
   105  
   106  | Parameters | Return  |
   107  |------------|---------|
   108  |            | `error` |
   109  
   110  **Example:**
   111  ``` go
   112  config.Load()
   113  ```
   114  
   115  #### config.LoadFrom
   116  
   117  You may need to load a configuration file from a custom path instead of using the standard one. `LoadFrom` lets you load a config file from the given path.
   118  
   119  | Parameters    | Return  |
   120  |---------------|---------|
   121  | `path string` | `error` |
   122  
   123  **Example:** load the config from the path given through a flag
   124  ``` go
   125  import (
   126    "flag"
   127    "os"
   128  
   129    "github.com/System-Glitch/goyave/v2"
   130    "github.com/System-Glitch/goyave/v2/config"
   131    
   132    //...
   133  )
   134  
   135  func handleFlags() {
   136  	flag.Usage = func() {
   137  		goyave.ErrLogger.Println("usage: " + os.Args[0] + " -config=[config]")
   138  		flag.PrintDefaults()
   139  		os.Exit(1)
   140  	}
   141  
   142  	flag.String("config", "", "JSON config file")
   143  	flag.Parse()
   144  
   145  	configDir := flag.Lookup("config")
   146  	path := configDir.Value.String()
   147  	if path != configDir.DefValue {
   148  		if err := config.LoadFrom(path); err != nil {
   149  			goyave.ErrLogger.Println(err)
   150  			os.Exit(goyave.ExitInvalidConfig)
   151  		}
   152  	}
   153  }
   154  
   155  func main() {
   156  	handleFlags()
   157  
   158  	if err := goyave.Start(route.Register); err != nil {
   159  		os.Exit(err.(*goyave.Error).ExitCode)
   160  	}
   161  }
   162  ```
   163  
   164  ### Using environment variables
   165  
   166  <p><Badge text="Since v3.0.0"/></p>
   167  
   168  You can use environment variables in your configuration file. Environment variables are identified by the following syntax: `${VARIABLE_NAME}`.
   169  
   170  ```json
   171  {
   172    "database": {
   173      "host": "${DB_HOST}"
   174    }
   175  }
   176  ```
   177  
   178  **Note:** *This syntax is strict. If the string doesn't start with `${` or doesn't end with `}`, it will not be considered an environment variable.*
   179  
   180  `int`, `float64` and `bool` values are supported. If the configuration entry is expected to be of one of these types, the content of the environment variable will be automatically converted. If the conversion fails, a configuration loading error will be returned.
   181  
   182  ### Getting a value
   183  
   184  All entries are accessible using **dot-separated paths**. If you want to access the `name` entry in the `app` category, the key will be `app.name`.
   185  
   186  #### config.Get
   187  
   188  Get a generic config entry. 
   189  
   190  Prefer using the `GetString`, `GetBool`, `GetInt` and `GetFloat` accessors. If you need a type not covered by those accessors, use `config.Get`. You may need to type-assert the returned value before using it. You can do so safely as the config values and types are validated.
   191  
   192  Panics if the entry doesn't exist.
   193  
   194  | Parameters   | Return                 |
   195  |--------------|------------------------|
   196  | `key string` | `interface{}` or panic |
   197  
   198  **Example:**
   199  ``` go
   200  config.Get("app.name") // "goyave"
   201  ```
   202  
   203  #### config.GetString
   204  
   205  Get a string config entry. Panics if the entry doesn't exist or is not a `string` or if it doesn't exist.
   206  
   207  | Parameters   | Return            |
   208  |--------------|-------------------|
   209  | `key string` | `string` or panic |
   210  
   211  **Example:**
   212  ``` go
   213  config.GetString("server.protocol") // "http"
   214  ```
   215  
   216  #### config.GetBool
   217  
   218  Get a bool config entry. Panics if the entry doesn't exist or is not a `bool` or if it doesn't exist.
   219  
   220  | Parameters   | Return          |
   221  |--------------|-----------------|
   222  | `key string` | `bool` or panic |
   223  
   224  **Example:**
   225  ``` go
   226  config.GetBool("app.debug") // true
   227  ```
   228  
   229  #### config.GetInt
   230  
   231  <p><Badge text="Since v3.0.0"/></p>
   232  
   233  Get an int config entry. Panics if the entry doesn't exist or is not an `int` or if it doesn't exist.
   234  
   235  | Parameters   | Return         |
   236  |--------------|----------------|
   237  | `key string` | `int` or panic |
   238  
   239  **Example:**
   240  ``` go
   241  config.GetInt("server.port") // 8080
   242  ```
   243  
   244  #### config.GetFloat
   245  
   246  <p><Badge text="Since v3.0.0"/></p>
   247  
   248  Get a float config entry. Panics if the entry doesn't exist or is not a `float64` or if it doesn't exist.
   249  
   250  | Parameters   | Return             |
   251  |--------------|--------------------|
   252  | `key string` | `float64` or panic |
   253  
   254  **Example:**
   255  ``` go
   256  config.GetInt("server.port") // 8080
   257  ```
   258  
   259  #### config.Has
   260  
   261  Check if a config entry exists.
   262  
   263  | Parameters   | Return |
   264  |--------------|--------|
   265  | `key string` | `bool` |
   266  
   267  **Example:**
   268  ``` go
   269  config.Has("app.name") // true
   270  ```
   271  
   272  ### Setting a value
   273  
   274  You can set a config value at runtime with the `config.Set(key, value)` function. Bear in mind that this change **temporary** and will be lost after your application restarts or if the config is reloaded. This function is mainly used for testing purposes. Values set using this function are still being validated: your application will panic and revert changes if the validation doesn't pass.
   275  
   276  Use `nil` to unset a value.
   277  
   278  - A category cannot be replaced with an entry.
   279  - An entry cannot be replaced with a category.
   280  - New categories can be created with they don't already exist.
   281  - New entries can be created if they don't already exist. This new entry will be subsequently validated using the type of its initial value and have an empty slice as authorized values (meaning it can have any value of its type)
   282  
   283  #### config.Set
   284  
   285  | Parameters          | Return          |
   286  |---------------------|-----------------|
   287  | `key string`        | `void` or panic |
   288  | `value interface{}` |                 |
   289  
   290  **Example:**
   291  ``` go
   292  config.Set("app.name", "my awesome app")
   293  ```
   294  
   295  ## Custom config entries
   296  
   297  Configuration can be expanded. It is very likely that a plugin or a package you're developing is using some form of options. These options can be added to the configuration system so it is not needed to set them in the code or to make some wiring.
   298  
   299  #### config.Register
   300  
   301  Register a new config entry and its validation.
   302  
   303  Each module should register its config entries in an `init()` function, even if they don't have a default value, in order to ensure they will be validated.
   304  
   305  Each module should use its own category and use a name both expressive and unique to avoid collisions. For example, the `auth` package registers, among others, `auth.basic.username` and `auth.jwt.expiry`, thus creating a category for its package, and two subcategories for its features.
   306  
   307  To register an entry without a default value (only specify how it will be validated), set `Entry.Value` to `nil`.
   308  
   309  Panics if an entry already exists for this key and is not identical to the one passed as parameter of this function. On the other hand, if the entries are identical, no conflict is expected so the configuration is left in its current state.
   310  
   311  | Parameters          | Return          |
   312  |---------------------|-----------------|
   313  | `key string`        | `void` or panic |
   314  | `kind config.Entry` |                 |
   315  
   316  **Example:**
   317  ``` go
   318  func init() {
   319    config.Register("my-plugin.name", config.Entry{
   320      Value:            "default value",
   321      Type:             reflect.String,
   322      AuthorizedValues: []interface{}{},
   323    })
   324    
   325    // Without a default value (only validation)
   326    config.Register("my-plugin.protocol", config.Entry{
   327      Value:            nil,
   328      Type:             reflect.String,
   329      AuthorizedValues: []interface{}{"ftp", "sftp", "scp"},
   330    })
   331  }
   332  ```
   333  
   334  ## Configuration reference
   335  
   336  ### App category
   337  
   338  | Entry           | Type     | Accepted values | Default     | Note                                                                                                           |
   339  |-----------------|----------|-----------------|-------------|----------------------------------------------------------------------------------------------------------------|
   340  | name            | `string` | any             | "goyave"    |                                                                                                                |
   341  | environment     | `string` | any             | "localhost" |                                                                                                                |
   342  | debug           | `bool`   | `true`, `false` | `true`      | When activated, print stacktrace on error and sends error message in response. **Disable this in production!** |
   343  | defaultLanguage | `string` | any             | "en-US"     | See the [Localization](./advanced/localization.html)                                                           |
   344  
   345  ### Server category
   346  
   347  | Entry         | Type      | Accepted values | Default     | Note                                                                      |
   348  |---------------|-----------|-----------------|-------------|---------------------------------------------------------------------------|
   349  | host          | `string`  | any             | "127.0.0.1" |                                                                           |
   350  | domain        | `string`  | any             | ""          | Used for URL generation Leave empty to use IP instead.                    |
   351  | protocol      | `string`  | "http", "https" | "http"      | See the [HTTPS](#setting-up-https) section                                |
   352  | port          | `int`     | any             | `8080`      |                                                                           |
   353  | httpsPort     | `int`     | any             | `8081`      |                                                                           |
   354  | timeout       | `int`     | any             | `10`        | Timeout in seconds                                                        |
   355  | maxUploadSize | `float64` | any             | `10`        | Maximum size of the request, in MiB                                       |
   356  | maintenance   | `bool`    | `true`, `false` | `false`     | If `true`, start the server in maintenance mode. (Always return HTTP 503) |
   357  
   358  #### TLS sub-category
   359  
   360  | Entry | Type     | Accepted values | Default | Note                  |
   361  |-------|----------|-----------------|---------|-----------------------|
   362  | cert  | `string` | any             | none    | Path to your TLS cert |
   363  | key   | `string` | any             | none    | Path to your TLS key  |
   364  
   365  ### Database category
   366  
   367  | Entry              | Type     | Accepted values                                 | Default                                 | Note                                                      |
   368  |--------------------|----------|-------------------------------------------------|-----------------------------------------|-----------------------------------------------------------|
   369  | connection         | `string` | "none", "mysql", "postgres", "sqlite3", "mssql" | "none"                                  | See the [Database](./basics/database.html) guide          |
   370  | host               | `string` | any                                             | "127.0.0.1"                             |                                                           |
   371  | port               | `int`    | any                                             | `3306`                                  |                                                           |
   372  | name               | `string` | any                                             | "goyave"                                |                                                           |
   373  | username           | `string` | any                                             | "root"                                  |                                                           |
   374  | password           | `string` | any                                             | "root"                                  |                                                           |
   375  | otions             | `string` | any                                             | "charset=utf8&parseTime=true&loc=Local" |                                                           |
   376  | maxOpenConnections | `int`    | any                                             | `20`                                    |                                                           |
   377  | maxIdleConnections | `int`    | any                                             | `20`                                    |                                                           |
   378  | maxLifetime        | `int`    | any                                             | `300`                                   | The maximum time (in seconds) a connection may be reused. |
   379  | autoMigrate        | `bool`   | `true`, `false`                                 | `false`                                 | When activated, migrate all registered models at startup  |
   380  
   381  
   382  ## Setting up HTTPS
   383  
   384  Setting up HTTPS on your Goyave application is easy. First, turn `server.protocol` to `https` in the config. Then, add the `server.tls.cert` and `server.tls.key` entries in the config. These two entries represent respectively the path to your TLS certificate and your TLS key.
   385  
   386  **Certbot example:**
   387  ``` json
   388  {
   389      ...
   390      "server": {
   391        "protocol": "https",
   392        "tls": {
   393          "cert": "/etc/letsencrypt/live/mydomain.com/cert.pem",
   394          "key": "/etc/letsencrypt/live/mydomain.com/privkey.pem"
   395        }
   396      },
   397      ...
   398  }
   399  ```
   400  
   401  Restart your server and you should now be able to connect securely to your Goyave application! All HTTP requests will automatically be redirected to HTTPS.