Lädt...

🔧 Refactoring Configuration Management in Go: From Inline to Structured Constants


Nachrichtenbereich: 🔧 Programmierung
🔗 Quelle: dev.to

Introduction

In this post, we will review a refactoring process for loading application configuration in Go.
The original implementation (referred to as Version 2) directly used hard-coded environment variable names inside the Load function.
The refactored version (Version 1) introduced constant definitions for environment variable keys and default values, improving both readability and maintainability.

Original Code (Version 2)

In the initial implementation, environment variable keys were inline literals within the Load function:

func Load() *Config {
    return &Config{
        EnvKeys:          os.Getenv("INPUT_ENV_KEY"),
        EnvValues:        os.Getenv("INPUT_ENV_VALUE"),
        OutputKeys:       os.Getenv("INPUT_OUTPUT_KEY"),
        OutputValues:     os.Getenv("INPUT_OUTPUT_VALUE"),
        GithubEnv:        os.Getenv("GITHUB_ENV"),
        GithubOutput:     os.Getenv("GITHUB_OUTPUT"),
        Delimiter:        getEnvWithDefault("INPUT_DELIMITER", ","),
        FailOnEmpty:      getBoolEnv("INPUT_FAIL_ON_EMPTY", true),
        TrimWhitespace:   getBoolEnv("INPUT_TRIM_WHITESPACE", true),
        CaseSensitive:    getBoolEnv("INPUT_CASE_SENSITIVE", true),
        ErrorOnDuplicate: getBoolEnv("INPUT_ERROR_ON_DUPLICATE", true),
        MaskSecrets:      getBoolEnv("INPUT_MASK_SECRETS", false),
        MaskPattern:      getEnvWithDefault("INPUT_MASK_PATTERN", ""),
        ToUpper:          getBoolEnv("INPUT_TO_UPPER", false),
        ToLower:          getBoolEnv("INPUT_TO_LOWER", false),
        EncodeURL:        getBoolEnv("INPUT_ENCODE_URL", false),
        EscapeNewlines:   getBoolEnv("INPUT_ESCAPE_NEWLINES", true),
        MaxLength:        getIntEnv("INPUT_MAX_LENGTH", 0),
        AllowEmpty:       getBoolEnv("INPUT_ALLOW_EMPTY", false),
        DebugMode:        getBoolEnv("DEBUG_MODE", false),
    }
}

  • Issues with This Approach
    • Magic Strings: Each environment variable name appears as a literal string, which increases the risk of typos.
    • Maintainability: If the environment variable name changes, it needs to be updated in multiple places.
    • Lack of Central Documentation: No clear central reference point for all supported environment variables.

Refactored Code (Version 1)

The refactored version introduces central constants for environment variable names and default values:

// Environment Variable Names Constants
const (
    // Input Environment Variables
    EnvKeyInput           = "INPUT_ENV_KEY"
    EnvValueInput         = "INPUT_ENV_VALUE"
    OutputKeyInput        = "INPUT_OUTPUT_KEY"
    OutputValueInput      = "INPUT_OUTPUT_VALUE"
    DelimiterInput        = "INPUT_DELIMITER"
    FailOnEmptyInput      = "INPUT_FAIL_ON_EMPTY"
    TrimWhitespaceInput   = "INPUT_TRIM_WHITESPACE"
    CaseSensitiveInput    = "INPUT_CASE_SENSITIVE"
    ErrorOnDuplicateInput = "INPUT_ERROR_ON_DUPLICATE"
    MaskSecretsInput      = "INPUT_MASK_SECRETS"
    MaskPatternInput      = "INPUT_MASK_PATTERN"
    ToUpperInput          = "INPUT_TO_UPPER"
    ToLowerInput          = "INPUT_TO_LOWER"
    EncodeURLInput        = "INPUT_ENCODE_URL"
    EscapeNewlinesInput   = "INPUT_ESCAPE_NEWLINES"
    MaxLengthInput        = "INPUT_MAX_LENGTH"
    AllowEmptyInput       = "INPUT_ALLOW_EMPTY"
    DebugModeInput        = "DEBUG_MODE"

    // GitHub Environment Variables
    GithubEnvVar    = "GITHUB_ENV"
    GithubOutputVar = "GITHUB_OUTPUT"
)

// Default Values Constants
const (
    DefaultDelimiter        = ","
    DefaultFailOnEmpty      = true
    DefaultTrimWhitespace   = true
    DefaultCaseSensitive    = true
    DefaultErrorOnDuplicate = true
    DefaultMaskSecrets      = false
    DefaultMaskPattern      = ""
    DefaultToUpper          = false
    DefaultToLower          = false
    DefaultEncodeURL        = false
    DefaultEscapeNewlines   = true
    DefaultMaxLength        = 0
    DefaultAllowEmpty       = false
    DefaultDebugMode        = false
)

// Config holds the application configuration
type Config struct {
    // Input/Output Keys and Values
    EnvKeys      string
    EnvValues    string
    OutputKeys   string
    OutputValues string

    // GitHub File Paths
    GithubEnv    string
    GithubOutput string

    // Input Processing Options
    Delimiter        string
    FailOnEmpty      bool
    TrimWhitespace   bool
    CaseSensitive    bool
    ErrorOnDuplicate bool
    AllowEmpty       bool

    // Value Transformation Options
    ToUpper        bool
    ToLower        bool
    EncodeURL      bool
    EscapeNewlines bool
    MaxLength      int

    // Security Options
    MaskSecrets bool
    MaskPattern string

    // Debug Options
    DebugMode bool
}

// Load loads configuration from environment variables
func Load() *Config {
    return &Config{
        // Input/Output Keys and Values
        EnvKeys:      os.Getenv(EnvKeyInput),
        EnvValues:    os.Getenv(EnvValueInput),
        OutputKeys:   os.Getenv(OutputKeyInput),
        OutputValues: os.Getenv(OutputValueInput),

        // GitHub File Paths
        GithubEnv:    os.Getenv(GithubEnvVar),
        GithubOutput: os.Getenv(GithubOutputVar),

        // Input Processing Options
        Delimiter:        getEnvWithDefault(DelimiterInput, DefaultDelimiter),
        FailOnEmpty:      getBoolEnv(FailOnEmptyInput, DefaultFailOnEmpty),
        TrimWhitespace:   getBoolEnv(TrimWhitespaceInput, DefaultTrimWhitespace),
        CaseSensitive:    getBoolEnv(CaseSensitiveInput, DefaultCaseSensitive),
        ErrorOnDuplicate: getBoolEnv(ErrorOnDuplicateInput, DefaultErrorOnDuplicate),
        AllowEmpty:       getBoolEnv(AllowEmptyInput, DefaultAllowEmpty),

        // Value Transformation Options
        ToUpper:        getBoolEnv(ToUpperInput, DefaultToUpper),
        ToLower:        getBoolEnv(ToLowerInput, DefaultToLower),
        EncodeURL:      getBoolEnv(EncodeURLInput, DefaultEncodeURL),
        EscapeNewlines: getBoolEnv(EscapeNewlinesInput, DefaultEscapeNewlines),
        MaxLength:      getIntEnv(MaxLengthInput, DefaultMaxLength),

        // Security Options
        MaskSecrets: getBoolEnv(MaskSecretsInput, DefaultMaskSecrets),
        MaskPattern: getEnvWithDefault(MaskPatternInput, DefaultMaskPattern),

        // Debug Options
        DebugMode: getBoolEnv(DebugModeInput, DefaultDebugMode),
    }
}


Question

I modified the code as above, but I think it got too long? Is it a lot? I'm a DevOps engineer and I'm also studying development.

...

🔧 Refactoring Configuration Management in Go: From Inline to Structured Constants


📈 74.82 Punkte
🔧 Programmierung

🔧 Refactoring Configuration Management in Go: From Inline to Structured Constants


📈 74.82 Punkte
🔧 Programmierung

🔧 Block vs. Inline vs. Inline-Block in CSS


📈 30.17 Punkte
🔧 Programmierung

🕵️ Low CVE-2022-1829: Inline google maps project Inline google maps


📈 30.17 Punkte
🕵️ Sicherheitslücken

🔧 Markdown notes assistant with extract/inline "refactoring"


📈 30.14 Punkte
🔧 Programmierung

🔧 Good Refactoring vs Bad Refactoring


📈 30.1 Punkte
🔧 Programmierung

🔧 Good Refactoring vs Bad Refactoring


📈 30.1 Punkte
🔧 Programmierung

📰 LLM-Powered Parsing and Analysis of Semi-Structured & Structured Documents


📈 27.81 Punkte
🔧 AI Nachrichten

🔧 Structured Content vs Page Builders: Why choose a structured approach?


📈 27.81 Punkte
🔧 Programmierung

🔧 Simplify SVG Management: Convert Paths to a Single JS File of Constants


📈 23.09 Punkte
🔧 Programmierung

🐧 From Lua to JSON: refactoring WirePlumber's configuration system


📈 22.75 Punkte
🐧 Linux Tipps

🔧 Go’s Constants: Beyond Basics


📈 19.81 Punkte
🔧 Programmierung

🕵️ XM^online Common Utils and Endpoints 0.2.1 Constants.java sql injection


📈 19.81 Punkte
🕵️ Sicherheitslücken

🔧 Enhancing Enum Constants in Laravel with Description and Label Attributes


📈 19.81 Punkte
🔧 Programmierung

🔧 Mastering the final Keyword in Java: Constants, Immutability, and More


📈 19.81 Punkte
🔧 Programmierung

🕵️ Extracting ROM constants from the 8087 math coprocessor's die


📈 19.81 Punkte
🕵️ Reverse Engineering

🔧 Constants, Object.freeze, Object.seal and Immutable in JavaScript


📈 19.81 Punkte
🔧 Programmierung

🔧 How Shadcn CLI uses error constants to improve code readability


📈 19.81 Punkte
🔧 Programmierung

🕵️ ActionApps constants.php3 GLOBALS[AA_INC_PATH] privilege escalation


📈 19.81 Punkte
🕵️ Sicherheitslücken

🔧 Python Doesn’t Support True Constants – So I Built “setconstant” to Fix That


📈 19.81 Punkte
🔧 Programmierung

🔧 Static Variables, Constants, and Methods


📈 19.81 Punkte
🔧 Programmierung

📰 Linux 6.11: Mehr Rust, Torvalds ergänzt "Runtime Constants"


📈 19.81 Punkte
📰 IT Nachrichten

🕵️ An IDA Python script to extract information from string constants


📈 19.81 Punkte
🕵️ Reverse Engineering

🔧 Tutorial 2: Swift Basics - Variables, Constants, and Data Types


📈 19.81 Punkte
🔧 Programmierung

🔧 Mastering Go: Guide to Type Declarations, Variables, and Constants


📈 19.81 Punkte
🔧 Programmierung

🔧 Introduction to Constants in GBase 8a MPP Cluster


📈 19.81 Punkte
🔧 Programmierung

📰 Protected API Calls and String Constants: Looting Dridex’s Candy Box


📈 19.81 Punkte
📰 IT Security

🔧 The Story of The Whispering Boxes: Ada Lovelace Unlocks the Secrets of Variables and Constants


📈 19.81 Punkte
🔧 Programmierung

🔧 Swift 101: Understanding Types, Variables, and Constants


📈 19.81 Punkte
🔧 Programmierung

🔧 July 10, 2024 Python | DataTypes, Variables, Constants


📈 19.81 Punkte
🔧 Programmierung

📰 Protected API Calls and String Constants: Looting Dridex’s Candy Box


📈 19.81 Punkte
📰 IT Security

🔧 Python Doesn’t Have True Constants—So I Built setconstant


📈 19.81 Punkte
🔧 Programmierung

🔧 Constants in Solidity


📈 19.81 Punkte
🔧 Programmierung

matomo