Sveriges mest populära poddar

Functional Design in Clojure

Episode 011: The Convention of Configuration

29 min • 11 januari 2019

Nate is worried about the hardcoded credentials in the code.

  • It's episode 011 on 01/11. It's binary!
  • "As a developer, you quickly learn what's under your control and what's not. Very little is under your control."
  • Don't accidentally check in the credentials.
  • "We need a configuration management system. Oh wait! That's a totally different problem."
  • What about putting the configuration into an EDN file?
  • Let's call it config.edn
  • Why EDN? Isn't JSON the "one, true format for config information"?
  • Pros of EDN:
    • native to Clojure
    • can have comments
    • is extensible
  • Why not environment variables?
  • Environment variables are great for production, but in development files are better.
  • Have to restart the REPL to change env variables.
  • Make a component that reads the config. That will reload config when you reset with component.repl.
  • Two main considerations:
    1. Dynamically reloading configuration during development
    2. Plumbing the configuration values through the app
  • Make a namespace for app.config
  • "Files are way more fungible than the environment."
  • We want both options: env for production and a file for dev.
  • Make two functions in app.config: from-env and from-file.
  • Use schema to make sure both functions return the same config map.
  • "A thing I have done before...you decide if it's clever."
  • Define a default configuration and then merge the config maps with that.
  • Better yet, from-env handles defaults and we merge the map from dev.edn into that.
  • Can use environ with Leiningen profiles. Still requires restarting the REPL.
  • Defaults should make sense for development, so you can just check out and run.
  • For bad config, we want helpful error messages, not stack traces.
  • What goes in configuration?
    • Items under your control
    • Items that vary
  • Twitter API URL does not vary.
  • Even if Twitter provided sandbox URLs, those URLs don't vary. The config option should be "production" and "sandbox", not the URL. The wrapper code will select the right URL.
  • Avoid the nonsense of trying to infer "sandbox" from reading the URL.
  • "The hallmark of good design is: the less thinking you have to do, the better."
  • "The more semantic the config, the less thinking you have to do."
  • It's important to think about the data first, where it comes from, and where it goes.

Clojure in this episode:

  • merge
  • try, catch
  • slurp
  • clojure.edn/read-string
  • environ.core/env
  • component.repl/reset

Related projects:

Code sample from this episode:

(ns app.config
  (:require
    [clojure.edn :as edn]
    [environ.core :refer [env]]))

(defn from-env []
  {:twitter-key (or (env :twitter-key) "")
   :twitter-secret (or (env :twitter-secret) "")
   :initial-tweets (or (env :initial-tweets) 20))

(defn config []
  (merge (from-env)
         (edn/read-string (try (slurp "dev.edn") (catch Throwable e "{}")))))
Förekommer på
00:00 -00:00