Bem-vindo ao meu blog!

Continuamos nossa jornada de estudo e revisão dos 12 fatores para o desenvolvimento de aplicações modernas, inspirados pelos livros do lendário Martin Fowler.

Nos artigos anteriores, discutimos o primeiro e segundo fatores, a Base de Código e Gerenciamento de Dependências. Hoje, vamos abordar o terceiro fator:

Configurações

As configurações de uma aplicação são todas as opções e parâmetros que podem variar entre diferentes ambientes (desenvolvimento, teste, produção, etc.). Esses parâmetros incluem, por exemplo, informações de conexão a banco de dados, chaves de API e credenciais de acesso.

Separe as Configurações do Código e use Variáveis de Ambiente

Uma das principais práticas do terceiro fator é separar as configurações do código. Isso significa que as configurações não devem ser armazenadas no mesmo repositório do código-fonte da aplicação, nem devem ser codificadas diretamente no código.

Uma maneira comum e eficiente de armazenar e gerenciar configurações é usar variáveis de ambiente. As variáveis de ambiente são um meio de armazenar informações fora do código-fonte, tornando mais fácil a sua manutenção e garantindo maior segurança.

Benefícios

Seguindo a prática de separar configurações do código e utilizar variáveis de ambiente, você pode obter os seguintes benefícios:

  1. Segurança: Evita o vazamento de informações sensíveis, como chaves de API e credenciais de acesso.
  2. Flexibilidade: Permite a fácil adaptação da aplicação a diferentes ambientes, sem a necessidade de alterar o código-fonte.
  3. Versionamento: Evita a necessidade de versionar configurações, já que elas não fazem parte do código-fonte da aplicação.
  4. Facilita a colaboração: Facilita a colaboração entre desenvolvedores e equipes, uma vez que cada um pode ter suas próprias configurações locais sem afetar o ambiente de outros membros da equipe.
  5. Implantação simplificada: Facilita a implantação e configuração de novos ambientes, já que as configurações podem ser facilmente ajustadas sem a necessidade de alterar o código-fonte.
  6. Auditoria e rastreabilidade: Facilita o rastreamento e a auditoria das alterações nas configurações, pois elas são gerenciadas de forma independente do código.
  7. Escalabilidade: Permite a rápida adaptação das configurações quando a aplicação precisa ser escalada, sem a necessidade de modificar o código-fonte.

Exemplos e Ferramentas

Além das variáveis de ambiente, existem várias ferramentas e bibliotecas disponíveis para ajudar no gerenciamento de configurações em diferentes linguagens e frameworks, como:

  • dotenv (Node.js): Carrega variáveis de ambiente a partir de um arquivo .env em seu projeto.

Exemplo de uso do dotenv:

// Carregar a biblioteca dotenv
require('dotenv').config();

// Acessar variável de ambiente
const apiKey = process.env.API_KEY;
  • python-dotenv (Python): Permite o uso de arquivos .env para armazenar e gerenciar variáveis de ambiente em projetos Python, facilitando a separação entre configuração e código, e mantendo as configurações sensíveis fora do sistema de controle de versão.

Exemplo de uso do python-dotenv:

# app.py
import os
from flask import Flask
from dotenv import load_dotenv

load_dotenv()
app = Flask(__name__)
port = os.environ.get('PORT', 5000)

@app.route('/')
def hello_world():
    return 'Olá, Mundo!'

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=port)
  • Viper (Golang): Gerencia configurações de aplicativos em Go usando uma variedade de fontes, como arquivos JSON, TOML, YAML, HCL, entre outros.

Exemplo de uso do Viper:

package main

import (
	"fmt"
	"github.com/spf13/viper"
)

func main() {
	viper.SetConfigName("config")
	viper.AddConfigPath(".")
	err := viper.ReadInConfig()

	if err != nil {
		panic(fmt.Errorf("Erro ao ler configuração: %s", err))
	}

	apiKey := viper.GetString("api_key")
	fmt.Println("API Key:", apiKey)
}

config-rs (Rust): Biblioteca de configuração para Rust que suporta arquivos JSON, TOML, YAML, HJSON e INI, entre outros.

Exemplo de uso do config-rs:

use config::{Config, File, Environment};
use serde::Deserialize;

#[derive(Debug, Deserialize)]
struct Settings {
    api_key: String,
}

fn main() {
    let mut settings = Config::default();

    settings
        .merge(File::with_name("config"))
        .unwrap()
        .merge(Environment::with_prefix("APP"))
        .unwrap();

    let settings: Settings = settings.try_into().unwrap();
    println!("API Key: {:?}", settings.api_key);
}

Conclusão

Neste artigo, abordamos o terceiro fator dos 12 fatores do desenvolvimento de software, que é o gerenciamento de configurações. Seguir as práticas apresentadas aqui pode ajudar a garantir a segurança, flexibilidade e escalabilidade da sua aplicação.

Fique ligado para os próximos artigos, onde continuaremos nossa jornada através dos 12 fatores, aprofundando ainda mais os conceitos e práticas que os compõem.

Até a próxima!