Upgrade to Pro — share decks privately, control downloads, hide ads and more …

BRACT: A Minimal DRY Application Framework

BRACT: A Minimal DRY Application Framework

IN/Clojure 2019 presentation on Bract: https://bract.github.io

Shantanu Kumar

January 12, 2019
Tweet

More Decks by Shantanu Kumar

Other Decks in Programming

Transcript

  1. Who Am I? - Principal Engineer, SAP Concur - Author,

    “Clojure High Performance Programming” - Bio https://kumarshantanu.github.io/ - Tends https://bangalore-clj.github.io/ - @kumarshantanu on Twitter, Github
  2. Project setup these days • Commonly repeated concerns • Config,

    Logging, Graceful shutdown, Exceptions • Ad hoc, often copied from old project (error prone) • Init steps are implicit, snowflakes, pets (vs cattle) • Have several projects? Beware of Drift over time
  3. App initialisation deficiencies • Initialisation model (as data, can we

    query it?) • Initialisation steps (as data, can we specify it?) • Sequence of steps (as data, can we declare it?) • Orthogonality (can we refactor the init sequence independent of the involved steps?) • Reloaded workflow (start, stop, reload, restart)
  4. App initialisation challenges • Skill gradient (How many people can

    do this?) • Repeating yourself (Even though they know) • Magical number 7 ± 2 (for business-code focus) • Libraries lack glue, not enough • Templates don’t offer any abstraction
  5. Plausible solution • Divide app into initialisation and runtime phases

    • Initialisation phase prepares app for runtime • First class initialisation artifacts (model, steps) • Different entry-points for deployment/develop envs • Different init sequence for deploy/dev envs
  6. Bract—Concepts • Context (map) as “rolling” initialisation state • Well

    known keys (shared among inducers) • Inducers `(fn [context]) -> context` as init steps • Potentially update context, have side effects • Specified declaratively, or programmatically • Context flows through inducers serially
  7. BRACT Some common context keys :bract.core/verbose? :bract.core/context-file :bract.core/config-files :bract.core/exit? :bract.core/cli-args

    :bract.core/config :bract.core/inducers :bract.core/deinit :bract.core/launch? :bract.core/launchers :bract.core/app-exit-code :bract.core/stopper
  8. BRACT: Inducer example (defn invoke-launchers ([context] (if (kdef/ctx-launch? context) (invoke-launchers

    context (kdef/ctx-launchers context)) (do (echo/echo "Launch not enabled, skipping launch.") context))) ([context launchers] (if (kdef/ctx-launch? context) (do (echo/echo "Launcher name:" launchers) (induce context launchers)) (do (echo/echo "Launch not enabled, skipping launch.") context))))
  9. Bract—Philosophy • NOT Convention over Configuration • Configuration defaults, overridable,

    powerful • Easy to reason about, not magical • Modular, each module offers capabilities • App runtime oblivious of Bract
  10. Bract—Modules • bract.core • bract.cli • bract.dev • bract.ring •

    gossamer.core • Inducers • Context resources • Config resources • Necessary dependencies Available modules Modules may offer
  11. Entry points • Regular CLI (project.clj —> {:main b.core.main}) •

    Tests (require [bract.core.dev]) • REPL (require [bract.core.dev]) • Lein plugins (e.g. lein-ring) • {:handler b.ring.dev/handler :init b.ring.dev/init!}
  12. Modules must integrate • Modules must integrate with app via

    framework • Module without Integration = Library • Hooks (plugins) vs configuration • Bract: Init steps ARE the glue! • Caveat: Writing excessive init steps is regressive!
  13. Gossamer Web framework based on Bract Try using: lein new

    gossamer <app> Image source: http://membean.com/exemplars/gossamer https://github.com/bract/gossamer.core
  14. Gossamer • Opinionated (most Bract modules are not) • Batteries

    included (web, logging, middleware) • Initialisation steps are prescribed/inherited • Overridable • Init steps evolve across versions in Gossamer • App benefits from Gossamer version bump
  15. Gossamer • Consumer-facing framework • May be customised for special

    needs • Web framework • Can do custom (batch, maint) jobs • May have own modules (in future)