ryoakg
3/6/2017 - 11:56 AM

compojure-demo.clj

(set-env! :dependencies '[[ring/ring-core "1.5.0"]
                          [ring-simpleweb-adapter "0.2.0"]
                          [compojure "1.5.2"]
                          [clj-http "2.3.0"]])

;;; more info: https://github.com/weavejester/compojure/wiki

;;; http server stuff
(require '[ring.adapter.simpleweb]
         '[compojure.core :refer :all]
         '[compojure.route :as route])
;;; http client stuff
(require '[clj-http.client :as http]
         '[clojure.java.browse :refer [browse-url]])

;;; * BASIC
(def conn
  (-> (routes
       (GET "/" []
            "<h1>Hello World.</h1>"))
      (ring.adapter.simpleweb/run-simpleweb
       {:port 8080})))

(:body (http/get "http://localhost:8080/"))
;; => "<h1>Hello World.</h1>"
(browse-url "http://localhost:8080/")

(.close conn)


;;; * RUN WITHOUT ring(WEB SERVER)
(let [app (routes (GET "/" []
                       "<h1>Hello World.</h1>"))]
  (app {:uri "/" :request-method :get}))
;; => {:status 200, :headers {"Content-Type" "text/html; charset=utf-8"}, :body "<h1>Hello World.</h1>"}


;;; * NAME RING APP WITH `defroutes`
(defroutes app
  (GET "/" ring-request
       (do (str "<h1>Hello World. (" (:uri ring-request) ")</h1>")))
  (route/not-found
   (do "<h1>Page not found</h1>")))

(app {:uri "/" :request-method :get})
;; => {:status 200, :headers {"Content-Type" "text/html; charset=utf-8"}, :body "<h1>Hello World</h1>"}
(app {:uri "/" :request-method :post})
;; => {:status 404, :headers {"Content-Type" "text/html; charset=utf-8"}, :body "<h1>Page not found</h1>"}

(def conn
  (ring.adapter.simpleweb/run-simpleweb
   app {:port 8080}))

(http/get "http://localhost:8080/")

(.close conn)


;;; * NAMED PARAMETERS
(defroutes app
  (GET "/hello/:name" [name]
       (str "Hello " name)))

(app {:uri "/hello/taro" :request-method :get})
;; => {:status 200, :headers {"Content-Type" "text/html; charset=utf-8"}, :body "Hello taro"}
(app {:uri "/hello/john" :request-method :get})
;; => {:status 200, :headers {"Content-Type" "text/html; charset=utf-8"}, :body "Hello john"}



;;; * NAMED PARAMETERS WITH MATCHING REGEX
(defroutes app
  (GET ["/file/:name.:ext" :name #".*", :ext #"(txt|md)"] [name ext]
    (str "File: " name \. ext)))

(app {:uri "/file/error.txt" :request-method :get})
;; => {:status 200, :headers {"Content-Type" "text/html; charset=utf-8"}, :body "File: error.txt"}
(app {:uri "/file/error.md" :request-method :get})
;; => {:status 200, :headers {"Content-Type" "text/html; charset=utf-8"}, :body "File: error.md"}
(app {:uri "/file/error.log" :request-method :get})
;; => nil


;;; * USING NAMED PARAMETERS AND RING-REQUEST
(defroutes app
  (GET "/hello/:name" {{name :name} :route-params
                       uri          :uri
                       :as          ring-request}
       (str uri ": Hello " name)))

(app {:uri "/hello/taro" :request-method :get})
;; => {:status 200, :headers {"Content-Type" "text/html; charset=utf-8"}, :body "/hello/taro: Hello taro"}
(app {:uri "/hello/john" :request-method :get})
;; => {:status 200, :headers {"Content-Type" "text/html; charset=utf-8"}, :body "/hello/john: Hello john"}


;;; COERCE NAMED PARAMETERS
(require 'compojure.coercions)

(defroutes app
  (GET "/id/:num" [num :<< compojure.coercions/as-int]
       (str (* 2 num))))

(app {:uri "/id/4" :request-method :get})
;; => {:status 200, :headers {"Content-Type" "text/html; charset=utf-8"}, :body "8"}
(app {:uri "/id/r" :request-method :get})
;; => nil


;;; * QUERY STRING
(require '[ring.middleware.params])

(defroutes app
  (GET "/posts" {{:strs [title author]} :query-params
                 :as req}
       (str "Title: " title ", Author: " author)))

(def conn
  (-> app
      ring.middleware.params/wrap-params
      (ring.adapter.simpleweb/run-simpleweb
       {:port 8080})))

(app {:uri "/posts" :request-method :get})
;; => {:status 200, :headers {"Content-Type" "text/html; charset=utf-8"}, :body "Title: , Author: "}
(app {:uri "/posts?title=Capital&author=Karl%20Heinrich%20Marx" :request-method :get})
;; => nil

(:body (http/get "http://localhost:8080/posts?title=Capital&author=Karl%20Heinrich%20Marx"))
;; => "Title: Capital, Author: Karl Heinrich Marx"

(.close conn)


;;; * STATIC FILES
(require '[clojure.java.io :as io])

(do
  (.mkdirs (io/file "res" "css"))
  (spit (io/file "res" "css" "style.css") "h1 {background-color: #ccc;}"))

(defroutes app
  (route/files "/"
               {:root "res"}))
;;; `compojure.route/resources` is also available,
;;; to provide files in classpath instead of file-system.

(def conn
  (ring.adapter.simpleweb/run-simpleweb app {:port 8080}))

(http/get "http://localhost:8080/css/style.css")
#_{:status 200,
   :headers
   {"Content-Length" "28",
    "Last-Modified" "Mon, 06 Mar 2017 10:11:36 GMT",
    "Content-Type" "text/css",
    "Connection" "close"},
   :body "h1 {background-color: #ccc;}",
   :request-time 6,
   :trace-redirects ["http://localhost:8080/css/style.css"],
   :orig-content-encoding nil}

(do
  (io/delete-file (io/file "res" "css" "style.css"))
  (io/delete-file (io/file "res" "css"))
  (io/delete-file (io/file "res")))

(.close conn)