Skip to content

Commit

Permalink
update readme
Browse files Browse the repository at this point in the history
  • Loading branch information
miladrahimi committed Oct 16, 2019
1 parent 6819da4 commit 80fa450
Showing 1 changed file with 136 additions and 29 deletions.
165 changes: 136 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ To install this package run the following command in the root of your project
go get github.com/golobby/config
```

### Simple example of usage
### A simple example
The following example demonstrates how to set and get a simple key/value.

```go
Expand All @@ -32,19 +32,23 @@ name, err := c.Get("name")
```

### Feeders
Feeders provide content of the configuration. Currently, these feeders are supported:
Feeders provide content of the configuration. Currently, these feeders exist out of the box:
* `Map`: Feeds a simple `map[string]interface{}`.
* `Json`: Feeds a JSON file.
* `JsonDirectory`: Feeds a directory of JSON files.

Of course, you are free to implement your feeders by implementing the `Feeder` interface.

You can pass your desired feeder through Options to the `New()` function this way:
```go
c, err := config.New(config.Options{
Feeder: ...,
Feeder: TheFeederGoesHere,
})
```

#### Feeding using Map
#### Feeding using Map feeder

You don't like config files!? It's OK you can pass a `Map` feeder to the Config initializer like this example:

```go
c, err := config.New(config.Options{
Expand All @@ -70,16 +74,17 @@ year, err := c.GetInt("year")
year, err := c.Get("duration")
// OR
duration, err := c.GetFloat("duration")

```

#### Feeding using Json
#### Feeding using Json feeder

Storing configuration data in a JSON file could be a brilliant idea. The example below shows how to use Json feeder.

A sample of JSON file:
`config.json`:

```json
{
"name": "MyAppUsingConfig",
"name": "MyAppUsingGoLobbyConfig",
"version": 3.14,
"numbers": [
1,
Expand Down Expand Up @@ -109,7 +114,7 @@ A sample of JSON file:
}
```

A sample of usage:
Go code:

```go
c, err := config.New(config.Options{
Expand All @@ -125,7 +130,10 @@ v, err := c.Get("users.0.address.city") // Delfan

#### Feeding using JsonDirectory

Example of directory structure:
If you have many configuration data and it doesn't fit in a single JSON file.
In this case, you can use multiple JSON files and feed them using JsonDirectory feeder like this example:

Sample project directory structure:

```
- main.go
Expand All @@ -135,86 +143,185 @@ Example of directory structure:
```

`app.json`:

```json
{"name": "MyApp", "version": 3.14}
{
"name": "MyApp",
"version": 3.14
}
```

`db.json`:

```json
{"sqlite": {"path": "app.db"}, "mysql":{"host": "localhost", "user": "root", "pass": "secret"}}
{
"sqlite": { "path": "app.db" },
"mysql": { "host": "localhost", "user": "root", "pass": "secret" }
}
```

Go code:

```go
c, err := config.New(config.Options{
Feeder: feeder.JsonDirectory{Path: "config"},
})

v, err := c.Get("app.version") // 3.14

v, err := c.Get("db.mysql.host") // localhost
```

### OS variables and environment files

#### OS variables

### Using OS variables and .env files
#### Using OS variables
Sometimes you need to use environment variables stored in OS alongside your configuration data.
You can refer to OS variables using a simple syntax, `${ VARIABLE }`, in the config values.
This example demonstrates how to use OS variables.

`db.json`:

```json
{"name": "MyApp", "port": "${ APP_PORT }"}
```

Go code:

```go
c, err := config.New(config.Options{
Feeder: feeder.Json{Path: "path/to/config.json"},
Feeder: feeder.Json{Path: "db.json"},
})

v, err := c.Get("name") // MyApp
v, err := c.Get("port") // equivalent to os.Getenv("APP_PORT")
```

#### Using .env files
If you need to have a default value in case of lacking OS variable you can use this syntax:

```
${ VARIABLE | DEFAULT }
```

Example of JSON file using OS variable:

```json
{"name": "MyApp", "port": "${ APP_PORT }"}
{"name": "MyApp", "port": "${ APP_PORT | 3306 }"}
```

#### environment files

You maybe want to use ".env" files. Good news! It's so easy to work with environment files.
You can pass an environment file path alongside your config feeder when you initialize a new instance of Config.

Sample project directory structure:

```
- main.go
- .env
- config.json
```

`config.json`:

```json
{"name": "MyApp", "key": "${ APP_KEY }", "port": "${ APP_PORT | 3306 }"}
```

`.env`:

```env
APP_PORT=8585
APP_KEY=secret
APP_PORT=
```

Go code:

```go
c, err := config.New(config.Options{
Feeder: feeder.Json{Path: "path/to/config.json"},
EnvFile: "path/to/.env",
Feeder: feeder.Json{Path: "config.json"},
EnvFile: ".env",
})

v, err := c.Get("port") // 8585
v, err := c.Get("name") // MyApp (from config.json)
v, err := c.Get("key") // secret (from .env)
v, err := c.Get("port") // 3306 (from config.json, the default value)
```

### Altogether!

In this section, we illustrate a complete example that shows many of the package features.

Sample project directory structure:

```
- main.go
- .env
- config
- - app.json
- - db.json
```

`app.json`:

```json
{
"name": "MyApp",
"key": "${ APP_KEY }"
}
```

#### Default Values
`db.json`:

```json
{"name": "MyApp", "port": "${ APP_PORT | 80 }"}
{
"sqlite": {
"path": "app.db"
},
"mysql": {
"host": "${ DB_HOST | localhost }",
"user": "${ DB_USER | root }",
"pass": "${ DB_PASS | secret }"
}
}
```

`.env`:

```env
APP_PORT=
APP_KEY=theKey
DB_HOST=127.0.0.1
DB_USER=
DB_PASS=something
```

Go code:

```go
_ := os.Setenv("DB_HOST", "192.168.0.13")

c, err := config.New(config.Options{
Feeder: feeder.Json{Path: "path/to/config.json"},
EnvFile: "path/to/.env",
Feeder: feeder.JsonDirectory{Path: "config"},
EnvFile: ".env",
})

v, err := c.Get("port") // 80
v, err := c.Get("app.name") // MyApp (from app.json)
v, err := c.Get("app.key") // theKey (from .env)
v, err := c.Get("db.mysql.host") // 192.168.0.13 (from OS variables)
v, err := c.Get("db.mysql.user") // root (from app.json, the default value)
v, err := c.Get("db.mysql.pass") // something (from .env)
```

#### Priority of value sources
What would happen if the value existed in the config file, the environment file, and the OS variables?
It's the order of the Config priorities:

1. OS Variables
1. Environment (.env) files
1. Default Value

So if the value was defined is OS variables, the Config would return it.
If it wasn't in OS variables, the Config would return the value stored in the environment file.
If it also wasn't in the environment file, it'd eventually return the value stored in the config file.

## Contributors

* [@miladrahimi](https://github.com/miladrahimi)
Expand Down

0 comments on commit 80fa450

Please sign in to comment.