Giter VIP home page Giter VIP logo

system's Introduction

system

What is it?

system owes to component both in spirit and in name. The component library helps implement the reloaded pattern as championed by Stuart Sierra. system is built on top of it, offering a set of readymade components. The idea is to expand the set over time with contributions from the community. It currently includes:

Motivation

A good REPL experience is a prerogative of Lisp languages. Reloaded components enable this goodness in Clojureland. Since they require an amount of setup, the first steps when starting a new project are generally devoted to infrastructure. My first attempt to tackle the boilerplate was a Leiningen template. The problem is that Leiningen templates are hard to maintain and difficult to retrofit on existing projects. I was finding myself repeatedly updating the template for future use. Then it dawned on me that a library would better fit the bill. And so system came to light. It’s now the first dependency I add to any project, allowing me to focus from the get-go on the substance of my application.

Is it good?

Yes.

Installation

Add the following to the Leiningen dependencies in project.clj.

http://clojars.org/org.danielsz/system/latest-version.svg

Example project

An example project is available under the example folder. It is a self-contained project that will help you get started.

Usage

First, assemble your system(s) in a namespace of your choosing. Here we define two systems, development and production.

(ns my-app.systems
  (:require 
   [com.stuartsierra.component :as component]
   (system.components 
    [jetty :refer [new-web-server]]
    [repl-server :refer [new-repl-server]]
    [datomic :refer [new-datomic-db]]
    [mongo :refer [new-mongo-db]])
   [my-app.webapp :refer [handler]]
   [environ.core :refer [env]]))

(defn dev-system []
  (component/system-map
   :datomic-db (new-datomic-db (env :db-url))
   :mongo-db (new-mongo-db)
   :web (new-web-server (env :http-port) handler)))

(defn prod-system []
  "Assembles and returns components for an application in production"
  []
    (component/system-map
     :datomic-db (new-datomic-db (env :db-url))
     :mongo-db (new-mongo-db (env :mongo-url))
     :web (new-web-server (env :http-port) handler)
     :repl-server (new-repl-server (env :repl-port))))

Then, in user.clj:

(ns user
  (:require [reloaded.repl :refer [system init start stop go reset]]
            [my-app.systems :refer [dev-system]]))

(reloaded.repl/set-init! dev-system)

You can then manipulate the system in the REPL: (go), (reset) or (stop). The system map is accessible at any time, it resides in a var named, as you can guess, #'system.

In production, in core.clj:

(ns my-app.core
  (:gen-class)
  (:require [my-app.systems :refer [prod-system]]))

(defn -main 
  []
  "Start the application"
  (alter-var-root #'prod-system component/start)

Or, if you want to keep a handler on your system in production:

(ns my-app.core
  (:gen-class)
  (:require [reloaded.repl :refer [system init start stop go reset]]
            [my-app.systems :refer [prod-system]]))

(defn -main 
  []
  "Start the application"
  (reloaded.repl/set-init! prod-system)
  (go))

defsystem

A convenience macro, defsystem, allows you to declare systems succinctly:

(ns my-app.systems
  (:require 
   [system.core :refer [defsystem]]
   (system.components 
    [jetty :refer [new-web-server]]
    [repl-server :refer [new-repl-server]]
    [datomic :refer [new-datomic-db]]
    [mongo :refer [new-mongo-db]])
   [my-app.webapp :refer [handler]]
   [environ.core :refer [env]]))

(defsystem dev-system 
  [:datomic-db (new-datomic-db (env :db-url))
   :mongo-db (new-mongo-db)
   :web (new-web-server (env :http-port) handler)])

(defsystem prod-system 
  [:datomic-db (new-datomic-db (env :db-url))
   :mongo-db (new-mongo-db (env :mongo-url))
   :web (new-web-server (env :http-port) handler)
   :repl-server (new-repl-server (env :repl-port))])

Note: Component allows you to define dependency relationships within systems. Please don’t use said macro for those cases. Be sure to consult component’s API to see the range of options available to you.

At runtime

At runtime, the system var can be used anywhere after requiring it from the reloaded.repl namespace:

(ns front-end.webapp.handler
 (:require [reloaded.repl :refer [system]]))

For a discussion around a specifice example (i.e. Sente and http-kit), please look here.

The Reloaded pattern

Here are a couple of links that are sure to shed more light on the motivations of the reloaded workflow.

The canonical reference: My Clojure Workflow, Reloaded

And more references touching on the topic.

Contributing

Please fork and issue a pull request to add more components. Please don’t forget to include tests. You can refer to the existing ones to get started.

Credits

I wish to thank Stuart Sierra for the pioneering and guidance. Special thanks to James Reeves for the reloaded.repl library and general inspiration. Thanks to Peter Taoussanis, the friendly OSS contributor, who helped to ‘componentize’ sente, an amazing library on its own right.

system's People

Watchers

Lambder avatar James Cloos avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.