Adjusting the database connection

In essence, the Configuration principle of the 12 Factor-Application Pattern states that an application's configuration and an application's code should be completely independent of each other. Our hipstr application currently violates this principle in a key area: the database connection. This, however, is easily resolved.

Creating the profiles.clj file

For our development server, we will create profiles.clj and have the lein-env plugin generate the .lein-env file. Currently, our hipstr.models.connection/db-spec expects 5 settings: :classname, :subprotocol, :subname, :user, and :password.

Theoretically, we could transfer the entire db-spec map into the profiles.clj file, such as shown below:

{:dev {:env {:db-spec {:classname   "org.postgresql.Driver"
                       :subprotocol "postgresql"
                       :subname     "//localhost/postgres"
                       :user        "hipstr"
                       :password    "p455w0rd})

We could then modify hipstr.models.connection/db-spec to just the following:

(ns hipstr.models.connection 
  (:require [environ.core :refer [env]]))
(def db-spec (env :db-spec))

However, this would prove to be our fall from grace during deployment outside the development server, because environ does not support embedded configuration maps for environment variables or Java system properties. As such, we need to flatten our settings. So do the following steps:

  1. Create a new profiles.clj file alongside our project.clj file in the hipstr project folder.
  2. Add the following map:
    {:dev {:env {:dev? true
           :db-classname  "org.postgresql.Driver"
           :db-subprotocol "postgresql"
           :db-subname     "//localhost/postgres"
           :db-user             "hipstr"
           :db-password     "p455w0rd"}}}

The next time you run lein ring server, the .lein-env file will be generated and the above profiles.clj map will be included, thus allowing environ to find the settings when called upon.

Modifying the hipstr.models.connection namespace

Next, we need to modify our hipstr.models.connection namespace to make use of the environ library:

  1. Adjust the hipstr.models.connection namespace to include environ:
    (ns hipstr.models.connection
      (:require [environ.core :refer [env]]))
  2. Next, simply replace each hardcoded database configuration value with the environ equivalent:
    (def db-spec {:classname    (env :db-classname)
                  :subprotocol  (env :db-subprotocol)
                  :subname      (env :db-subname)
                  :user         (env :db-user)
                  :password     (env :db-password)})

That's all we have to do! Our database connection can now read configuration from anywhere environ resolves the key!

Before we restart our development server however, let's adjust the migratus-config in the hipstr.handler namespace. In the hipstr.handler namespace, perform the following steps:

  1. Add a reference to our hipstr.models.connection/db-spec in the :require:
    (ns hipstr.handler
      (:require [compojure.core :refer [defroutes]]
                    [hipstr.models.connection :refer [db-spec]]
                ...)
  2. Remove the hardcoded :db map in our migratus-config, and instead use the referred db-spec:
    (def migratus-config
      {:store :database
       :migration-dir "migrations"
       :migration-table-name "_migrations"
       :db db-spec})

That's it! All of our database references are now using an external configuration. Restart your development server and create a new user, and you'll find that everything behaves the same way.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.17.79.206