Search code examples
clojuremacroscompojure

How to execute a database entry based on a html form post in clojure?


I am working with Compojure and ran into a problem with the macro "defroutes". My error is caused by the macro not evaluating a function. Here is an example of my routes and what I'm trying to do. Stars added for emphasis.

(defroutes simple-routes
  (GET "/", [],  form)
  ***(POST "/", [count, day], (do (create-entry count day) "Success!")***
  (GET "/attendance/", [], response)
  (resources "/")
  (not-found "404")

create-entry functions correctly when evaluated as such (create-entry 1 2) Inputting the two integers into the database. However it does not get run when placed in the above route macro. What could I do to get the two integer values from an html form post to be run as (create-entry count day)? (yes I know this code is not stand alone but the above code is the only code in question, as everything else runs fine.)


Solution

  • You can use Compojure binding of form params along with params coercion:

    (ns compojure-hello-world.handler
      (:require [compojure.core :refer :all]
                [compojure.route :as route]
                [compojure.coercions :refer :all]
                [ring.middleware.params :refer [wrap-params]]))
    
    (defroutes app-routes
      (GET "/" [] "Hello World")
      (POST "/" [count :<< as-int
                 day   :<< as-int]
                  (println "Count" count (type count) "Day" day (type day))           
                  (create-entry count day)
                  {:status 200 :body "Done"})
      (route/not-found "Not Found"))
    
    (def app
      (-> app-routes (wrap-params)))
    

    Then you can test it:

    curl -X POST --data "count=1&day=2"  http://localhost:3000/