Dicese Slex Dishes on Clean Code Configuration
All but the most trivial code needs some configuration and setup to do meaningful work. From database connection strings to IoC container initialization — even the lowly idempotent Hello World app is dependent on the implicit default configuration of its environment.
In the physical world, we like instrument clusters, dashboards, things that bring together all the buttons, switches, dials, and toggles into one convenient place. Configuring our code should be no different. Wouldn’t it be nice if managing all the config things were as easy as driving your car?
Well, meet your new friend, Dicese Slex, (Dih-CHESS-ee Slex, for the uninitiated). He’s a cool don wearing silk system threads, and he’s here to spruce up your configs. At the very least, he hopes to get you thinking about the importance of code configs.
How so? Each two-letter slice of his mnemonified name will help you remember an important aspect of config taming. Indeed, let’s talk about making our configs discoverable, centralized, self-documenting, slim, and explicit. 😎
We will examine each of these attributes of config quality in turn, but first — what are some indications that your configs might need some attention?
Symptoms of poorly-factored configs
“Well I’ve got these scattered configs lying on my bedroom floor” 🎵
What are some symptoms that your configs need some TLC? (Taming Lame Configuration)
- Hello World app requires loads of documentation about the location and meaning of different configuration options? You just might be doing it wrong. Configuration options should be as self-documenting as possible.
- You keep breaking tests (or prod!) because you forget to update that one thing, five projects over and three folders deep.
- New hires can’t figure out how to ___ because they need to tweak a deep registry setting or set an undocumented environment variable.
- Thousands of configuration locations and parameters, which should have been included in the copious documentation mentioned above, are instead distributed in a fragile P2P “wetware” network of Tribal knowledge.
Whew, that sounds rough! Allow Dr. Slex to soothe your aching head.
Dr. Dicese Slex breaks down config management
Slex firmly and eponymously believes that code configs should be:
- Discoverable: You can find it
- Centralized: It’s all in one place
- Self-documenting: You can understand it
- Slim: Minimizes number of configuration parameters
- Explicit: No sneaky configuration settings
Let’s dig deeper.
This one’s so important I mentioned it first. Save the best for, uh… first!
All configuration should be in one place, like a Web.config file. If that isn’t possible, at least attempt to centralize all configs into their own project or folder. If you agree on a standard approach, you’ll almost never have to go in search of a configuration parameter again. They’ll all be right there in “Engineering.”
Your real world house has a few configuration parameters like which electrical circuits are closed and whether or not your gas is turned on. Fortunately your circuit breaker configuration is generally centralized within a single electrical panel. What if every time your curling iron and cryptomining rig tripped a circuit you had to remember where in the house (or worse, the neighbor’s house) its corresponding circuit breaker was located? “Ah, here it is! — Under the couch!”
If your configs are centralized, they’ll likely be discoverable as well, but it still bears saying: Don’t centralize your configs and then hide them in an obscure corner of the universe (where they’ll end up destroyed pointlessly by Vogons).
Configs are super important, just like Engineering on a starship. Make sure even the greenest noob won’t struggle to find your config dashboard, even if that “dashboard” is just a simple file. Remember, “huge pulsing warp core”, not rando panel on deck 5.
DISABLE_USER_EMAILS sounded like a great idea for an environment variable two months ago. Now you’re not sure what it was for, or what kind of data it’s expecting. Is it a boolean, a string array, a function even?
First give the configuration setting a super obvious name. Then remember that “super obvious” today could mean “what in the world?” six months from now. Consider adding some comments explaining its purpose and what sort of data it expects. The comment should include an example. If there is a default value, make sure all of your defaults follow the common case, happy path.
The more configs you throw at a system, the tougher it becomes to maintain.
Before carelessly tossing in another configuration parameter, ask yourself if this candidate config is really necessary. It doesn’t necessarily have to “spark joy,” but it does need to be pulling its own weight. Is it something you can extrapolate from existing configs with just a little more effort?
Configuration settings come in different flavors. You’ve got your unabashed explicit configuration settings like connection strings and IP addresses. You look at one of those and you instantly recognize it as a configuration setting. This is good.
Other forms of configuration are a more subtle. What if your app supports a REST API that allows for runtime administrative (re)configuration? Does everybody know about it? Are the supported parameters obvious or documented? Does tweaking one setting have unobvious side effects like enabling or disabling ten other settings? ← This is complex, and less good.
Bottom line: Make it super obvious how to configure your system. If you can’t make it obvious, then document it. If you document it, they will come. If you don’t document it, they will still come… with pitchforks.
Keep it together, amigo
You’ve just been Slex’d, DiCeSe SlEx’d.😎🍸 Now head out there and apply his clean, minimalist code salve to your own configs.