Now that we can talk to a database we are on the cusp of adding actual interesting behavior to this server.
First though, we should take a minute to structure the rest of the code for growth.
Right now we only have the "index" page (/
) and the /goodbye
route, so it might not
be clear why we would bother reorganizing anything.
It happens that when you make a server that serves HTML you tend to have multiple routes serving any given page. What we want is for no route - or as few routes as possible - to be used for serving multiple pages. If we don't take this step early it can become a hairball.
So in src/example/hello/routes.clj
you should have:
(ns example.hello.routes
(:require [example.system :as-alias system]
[hiccup2.core :as hiccup]
[next.jdbc :as jdbc]))
(defn hello-handler
[{::system/keys [db]} _request]
(let [{:keys [planet]} (jdbc/execute-one!
db
["SELECT 'earth' as planet"])]
{:status 200
:headers {"Content-Type" "text/html"}
:body (str
(hiccup/html
[:html
[:body
[:h1 (str "Hello, " planet)]]]))}))
In src/example/goodbye/routes.clj
you would have:
(ns example.goodbye.routes
(:require [hiccup2.core :as hiccup]))
(defn goodbye-handler
[_system _request]
{:status 200
:headers {"Content-Type" "text/html"}
:body (str
(hiccup/html
[:html
[:body
[:h1 "Goodbye, world"]]]))})
And finally back in src/example/routes.clj
you should reference those two new namespaces.
(ns example.routes
(:require [clojure.tools.logging :as log]
[example.goodbye.routes :as goodbye-routes]
[example.hello.routes :as hello-routes]
[hiccup2.core :as hiccup]
[reitit.ring :as reitit-ring]))
(defn routes
[system]
[["/" {:get {:handler (partial #'hello-routes/hello-handler system)}}]
["/goodbye" {:get {:handler (partial #'goodbye-routes/goodbye-handler system)}}]])
(defn not-found-handler
[_request]
{:status 404
:headers {"Content-Type" "text/html"}
:body (str
(hiccup/html
[:html
[:body
[:h1 "Not Found"]]]))})
(defn root-handler
[system request]
(log/info (str (:request-method request) " - " (:uri request)))
(let [handler (reitit-ring/ring-handler
(reitit-ring/router
(routes system))
#'not-found-handler)]
(handler request)))
reitit
routesBy doing this we can hook up multiple handlers at once and also have a place to later put page specific middleware.
src/example/hello/routes.clj
:
(ns example.hello.routes
(:require [example.system :as-alias system]
[hiccup2.core :as hiccup]
[next.jdbc :as jdbc]))
(defn hello-handler
[{::system/keys [db]} _request]
(let [{:keys [planet]} (jdbc/execute-one!
db
["SELECT 'earth' as planet"])]
{:status 200
:headers {"Content-Type" "text/html"}
:body (str
(hiccup/html
[:html
[:body
[:h1 (str "Hello, " planet)]]]))}))
(defn routes
[system]
[["/" {:get {:handler (partial #'hello-handler system)}}]])
src/example/goodbye/routes.clj
:
(ns example.goodbye.routes
(:require [hiccup2.core :as hiccup]))
(defn goodbye-handler
[_system _request]
{:status 200
:headers {"Content-Type" "text/html"}
:body (str
(hiccup/html
[:html
[:body
[:h1 "Goodbye, world"]]]))})
(defn routes
[system]
[["/goodbye" {:get {:handler (partial #'goodbye-handler system)}}]])
src/example/routes.clj
(ns example.routes
(:require [clojure.tools.logging :as log]
[example.goodbye.routes :as goodbye-routes]
[example.hello.routes :as hello-routes]
[hiccup2.core :as hiccup]
[reitit.ring :as reitit-ring]))
(defn routes
[system]
[""
(hello-routes/routes system)
(goodbye-routes/routes system)])
...