munk
munk

Reputation: 12983

Compojure not getting request body

I have an application using Compojure with this sort of endpoint

(defroutes routes
  (POST "/api/v1/echo" req (str req))

(def http-handler
  (reload/wrap-reload (wrap-defaults #'routes api-defaults)))

(defn run-web-server []
    (run-jetty http-handler {:port 10555 :join? false}))

When I try this curl request

curl -X POST -H "Content-Type: application/json" http://localhost:10555/api/v1/echo -d '{"hello": "world"}'

I get this response

{:ssl-client-cert nil, :remote-addr "0:0:0:0:0:0:0:1", :params {}, :route-params {}, :headers {"accept" "*/*", "user-agent" "curl/7.43.0", "content-type" "application/json", "content-length" "18", "host" "localhost:10555"}, :server-port 10555, :content-length 18, :form-params {}, :query-params {}, :content-type "application/json", :character-encoding nil, :uri "/api/v1/echo", :server-name "localhost", :query-string nil, :body #object[org.eclipse.jetty.server.HttpInput 0x4317e5fa "org.eclipse.jetty.server.HttpInput@4317e5fa"], :scheme :http, :request-method :post}%

What I'm expecting to see is {"hello", "world"} somewhere in that response, but it's not there. I see there is :body HttpInput, but when I try (prn (-> req :body .read)) it outputs 123. Because (= "{\"hello\", \"world\"}" 123) => false, I'm a little lost about what to try next.

curl -X POST -H "Content-Type: application/x-www-form-urlencoded" http://localhost:10555/api/v1/echo -d "foo=1&bar=2" does work as expected and returns :params {:foo "1", :bar "2"}, but I'd rather submit json. I know I could use compojure-api probably, but I'm curious why this behaves this way.

Upvotes: 2

Views: 3123

Answers (2)

Taha Husain
Taha Husain

Reputation: 312

Try adding wrap-json-params middleware in your handler.

Upvotes: 0

Diego Basch
Diego Basch

Reputation: 13069

You need to use the ring-json middleware, particularly wrap-json-body to parse json parameters:

The wrap-json-body middleware will parse the body of any request with a JSON content-type into a Clojure data structure, and assign it to the :body key.

This is the preferred way of handling JSON requests.

Upvotes: 6

Related Questions