Carregando configurações de arquivos toml

Muitos programas que escrevemos precisam de informações para configurar uma conexão com banco de dados, enviar informações para uma API de terceiros e etc…

Existem várias formas para nosso programa receber essas informações, dentre elas, a pior sendo colocar as informações diretamente no código, pois, além de ficar difícil para manter as várias configurações por ambiente, existe o fator segurança, já que os dados ficarão expostos no seu Github, Gitlab ou qualquer outro versionador de código que você utilizar.

Outra forma para fazer isso seria utilizando variáveis de ambiente, mas caso você não esteja usando Kubernetes, essa maneira pode ser muito trabalhosa para se manter.

Por isso, nesse post vamos ver como podemos manter essas configurações fora do nosso código usando arquivos toml.

Primeira coisa que precisamos fazer é instalar uma dependência que vai nos ajudar na conversão do conteúdo do nosso arquivo toml para uma struct, onde vamos armazenar nossa configurações.

$ go get github.com/BurntSushi/toml

Gosto de usar esse package pois ele foi implementado de forma similar aos packages json e xml, nativos da linguagem.

Agora vamos escrever um arquivo toml simples, onde vamos guardar nossas configurações para conexão com banco de dados.

host = "192.116.0.10"
user = "meu_usuario"
pass = "1234abc?"
db = "aprendagolang"

Em nosso arquivo Go, vamos escrever uma struct onde esses dados possam ficar armazenados. Como nossos atributos do arquivo toml estão escritos com letra minúscula, precisamos adicionar uma propriedade em cada campo da struct para mapear o atributo do arquivo toml com o atributo da struct.

type Config struct {
    Host string `toml:"host"`
    User string `toml:"user"`
    Pass string `toml:"pass"`
    Db   string `toml:"db"`
}

Agora vamos adicionar uma variável global do tipo Config e escrever uma função init para carregar essas configurações.

var conf Config

func init() {
    data, err := os.ReadFile("config.toml")
    if err != nil {
        panic(err)
    }

    if _, err := toml.Decode(string(data), &conf); err != nil {
         panic(err)
    }
}

Para validar se conseguimos carregar os dados, vou adicionar uma função main só para teste.

func main() {
    fmt.Printf("Host: %s\n", conf.Host)
    fmt.Printf("User: %s\n", conf.User)
    fmt.Printf("Pass: %s\n", conf.Pass)
    fmt.Printf("Db: %s\n", conf.Db)
}

Agora é só fazer o go run main.go e ver o resultado impresso no terminal.

Abaixo vou deixar um exemplo de arquivo toml mais complexo só para referência.

[migration]
path = "./migration"

[database]
host = "192.116.0.10"
user = "meu_usuario"
pass = "1234abc?"
db = "aprendagolang"

[deploy]
clients = [123, 7782, 7612]

[servers]

  [servers.alpha]
  ip = "10.0.0.1"
  dc = "eqdc10"

  [servers.beta]
  ip = "10.0.0.2"
  dc = "eqdc10"

A struct para armazenar esses dados seria assim:

type Config struct {
    Migration MigrationConfig         `toml:"migration"`
    Database  DatabaseConfig          `toml:"database"`
    Deploy    DeployConfig            `toml:"deploy"`
    Servers   map[string]ServerConfig `toml:"servers"`
}

type MigrationConfig struct {
    Path string `toml:"path"`
}

type DatabaseConfig struct {
    Host string `toml:"host"`
    User string `toml:"user"`
    Pass string `toml:"pass"`
    Db   string `toml:"db"`
}

type DeployConfig struct {
    Clients []int `toml:"clients"`
}

type ServerConfig struct {
    IP string `toml:"ip"`
    DC string `toml:"dc"`
}

Deixem suas dúvidas nos comentários.

Até a próxima!


Subscreva

Fique por dentro de tudo o que acontece no mundo Go.

Deixe uma resposta