Difference between Godotenv and Viper in Golang
Tags: go, godotenv, viper
Published: 2023-08-29 10:17:01

Hai everyone, long time no see… I would like to share important information according to the title above.

We know that using `env` on golang project is very important and useful because with `env` we can manage the configuration in different development environments like development, staging and production. Without env we will have trouble changing the development environment from development to staging and vice versa.

In the golang project there are 2 libraries that are often used, `godotenv` and `viper`.

{% github https://github.com/joho/godotenv %}

{% github https://github.com/spf13/viper %}

Ok let's create the new project:
```bash
mkdir golang-viper
cd golang-viper
code .
```

Add `go.mod` with the same name project or other:
```bash
go mod init golang-viper
```
Install the `godotenv` and `viper` packages:
```bash
go get github.com/spf13/viper
go get github.com/joho/godotenv
```

## Using Viper ##
Create a new file `main.go` and copy the following code:
```go
package main

import (
 "fmt"
 "os"

 "github.com/spf13/viper"
)

func main() {
 viper.AddConfigPath("env")
 viper.SetConfigType("env")
 viper.SetConfigName("app")
 err := viper.ReadInConfig() // Find and read the config file
 if err != nil {             // Handle errors reading the config file
  panic(fmt.Errorf("fatal error config file: %w", err))
 }

 fmt.Println("DB_HOST from config:", viper.GetString("DB_HOST"))
 fmt.Println("DB_PORT from config:", viper.GetString("DB_PORT"))
}
```

Explained:
- `viper.AddConfigPath("env")` location `env` on your project, this project `env` in `env` directory.
- `viper.SetConfigType("env")` type of `env` file, in viper we use `env`, `yaml` and `json` file. This project uses `env` file.
- `viper.SetConfigName("app")` Name of the `env` file. This project `env` file will have the name `app.env`. You can create `env` file like `app.env` or `app.yaml` or `app.json`.

Next to read the configuration from `env` file you need to add `viper.ReadConfig()`. Next, to read the contents of the `env` we use `viper.getString` and put the key `env` file.

Below is the contents of the `env` file:
```
DB_HOST=localhost
DB_PORT=5432
```
Run the project:
```bash
go run .
```
```bash
➜  golang-viper go run . 
DB_HOST from config: localhost
DB_PORT from config: 5432
➜  golang-viper 
```

## Using Godotenv ##
Using this library is very simple and easy, just put the code below on your configuration file:
```go
package main

import (
    "log"
    "os"

    "github.com/joho/godotenv"
)

func main() {
  err := godotenv.Load()
  if err != nil {
    log.Fatal("Error loading .env file")
  }

  dbHost := os.Getenv("DB_HOST")
  dbPort := os.Getenv("DB_PORT")

  fmt.Println("dbHost: ", dbHost)
  fmt.Println("dbPort: ", dbPort)
}
```
Yes very easy with `godotenv` just put:
```go
godotenv.Load()
```

Run the project:
```bash
➜  golang-viper go run . 
dbHost: localhost
dbPort: 5432
➜  golang-viper
```

## Conclusion ##

- Using `godotenv` and `viper` actually depends on the project being made, if it's a simple project using `godotenv` is the right choice.
- The use of different `env` file options and we can flexibly set the viper option is the right one.

See you on next article...