Refactor handlers and unit testsλ︎
Refactor the unit tests to use the ring-mock library to test handler functions. Create separate handler functions for the routes in defroute
(there is only one custom handler at present).
(deftest dashboard-test
(testing "Testing elements on the dashboard"
(is (= (SUT/dashboard (mock/request :get "/"))
{:status 200
:body "Status Monitor Dashboard"
:headers {}}))))
Create a handler for the GET "/"
route
(defn dashboard
[request]
{:status (:OK http-status-code) :body "Status Monitor Dashboard" :headers {}})
Use the ring.util.response/response
function to create a well formed response map which has a status code of 200. This removes the need to type in the response map structure explicitly which potentially can introduce bugs.
In the current namespace ns
form, this function is required as an explicit refer, [ring.util.response :refer [response]]
, so its available to use by its unqualified name, response
.
Update the defroutes
definition to call this handler rather than hard coding the response map.
Run the Cognitect test runner to check the unit tests are still passing after the code refactor.
Helper functionsλ︎
The ring util library contains several other helper functions, bad-request
, not-found
and redirect
:
(ring.util.response/bad-request "Hello")
;;=> {:status 400, :headers {}, :body "Hello"}
(ring.util.response/created "/post/clojure-is-awesome")
;;=> {:status 201, :headers {"Location" "/post/clojure-is-awesome"}, :body nil}
(ring.util.response/redirect "https://clojure.org/getting-started/")
;;=> {:status 302, :headers {"Location" "https://clojure.org/getting-started/"}, :body ""}
The status
function converts an existing response to use a given status code (which can be anything). Use this with care and document what the status code means otherwise confusion will abound.
(ring.util.response/status (ring.util.response/response "Time for Cake!") 555)
;;=> {:status 555, :headers {}, :body "Time for Cake!"}
Ring utilities has functions for setting the header data for responses, content-type
, header
or set-cookie
.
(ring.util.response/content-type (ring.util.response/response "Hello") "text/plain")
;;=> {:status 200, :headers {"Content-Type" "text/plain"}, :body "Hello"}
(ring.util.response/header (ring.util.response/response "Hello") "X-Tutorial-For" "Practicalli")
;;=> {:status 200, :headers {"X-Tutorial-For" "Practicalli"}, :body "Hello"}
(ring.util.response/set-cookie (ring.util.response/response "Hello") "User" "123")
;;=> {:status 200, :headers {}, :body "Hello", :cookies {"User" {:value "123"}}}
wrap-cookies
middleware required
The set-cookie
function adds a new entry to the response map and requires the wrap-cookies
middleware to process correctly.
Handler functionsλ︎
A handler to return the incoming IP Address