Fork me on GitHub

I have a simple server running and when I try to access a POST endpoint, it doesn’t return the add-record handler, instead goes the the not-found handler. On the network tab, it actually says that the request method is a GET. What am I missing here? Also if I curl -v http:/ , I get HTTP/1.1 404 Not Found The GET endpoint works fine.

(ns practice.server
     [compojure.core :refer [defroutes GET POST]]
     [org.httpkit.server :as server]
     [ring.middleware.defaults :refer [wrap-defaults site-defaults]]
     [compojure.route :as route]))

(defn add-record 
  (println req))

(defn get-bar 
  {:status 200
   :headers {"Content-Type" "text/html"}
   :body "Hello World"})

(defroutes app-routes
  (POST "/foo" [] add-record)
  (GET "/bar" [] get-bar)
  (route/not-found "Error, page not found!"))

(defn web-server
  [& args]
  (let [port (Integer/parseInt (or (System/getenv "PORT") "3000"))]
    ; Run the server with Ring.defaults middleware
    (server/run-server (wrap-defaults #'app-routes site-defaults) {:port port})
    (println (str "Running webserver at http:/" port "/"))))


@audyarandela That is because your handler returns nil (from the println call) and Compojure treats a nil handler response as "doesn't match" and moves on to the next possible route match, which will be not-found in this case.


As soon as you make add-record return a response, it will work as you expect.


Thanks for your response! I just tried adding a simple response, same as get-bar and still was getting the same 404 error.


Oddly enough, when I change the POST route to ANY it works. But thats not REST-y and the request method on the network tab shows GET still


Are you sure you're sending a POST request with curl? I thought you needed -d to POST data...


Yes you’re correct, -d is needed for POST. getting a different error now, <h1>Invalid anti-forgery token</h1>


When trying to access it via web browser, all I was getting was that 404 error and seeing that the request method was GET, time to google some more with the new error lol


Thanks @seancorfield, I disabled the :security and :anti-forgery in site-defaults and was able to curl through. (its only a practice app to understand the tech)


Yeah, to use curl when you have CSRF in place you need to GET the form first, copy the anti-forgery token in it, then POST the form fields and the anti-forgery token.


The idea behind CSRF is that you can't just randomly POST stuff to an app -- you have to actually fill in the form fields and then submit the form. That's the security aspect of it 🙂


Yea that makes sense now lol. Probably also why the web browser showing an error because it doesn’t have the right credentials


I think you have to actually add stuff to the form so that the CSRF token is available as a hidden field... I've never used it myself (I mostly do REST APIs which use the API defaults, not the site default).


ring-defaults is good for that -- there's API, secure API, web site, and secure web site I think as four base profiles.