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.