11
votes

I'm trying to use ring-json's wrap-json-response middleware within my compojure app. I have a simple GET handler that returns a map, like {:foo 1}, and when I hit the URL, ring responds with text/plain and an empty response body. I can't seem to get it to respond with the JSON version of the map.

Here's my handler code:

(ns localshop.handler
  (:use compojure.core)
  (:require [localshop.routes.api.items :as routes-api-items]
            [ring.middleware.json :as middleware]
            [compojure.handler :as handler]
            [compojure.route :as route]))

;; map the route handlers
(defroutes app-routes
  (context "/api/item" [] routes-api-items/routes))

;; define the ring application
(def app
  (-> (handler/api app-routes)
      (middleware/wrap-json-body)
      (middleware/wrap-json-params)
      (middleware/wrap-json-response)))

The route handler function literally just returns a map, so the code for that is simple enough that I think I could leave out. If returning a map from a compojure route handler is the problem, then perhaps that's it?

2

2 Answers

15
votes

Check out this. Basically if you return {:body {:my-map "hello"}} then it will work fine.

1
votes

Stumbe similar issue, when writing REST API.

When handler return vector, i get exception that no implementation of method render for PersistentVector in Renderable protocol in compojure.

When return map, headers is empty.

When return sequence, i get 'text/html'. So, i think it's good to be extend Renderable in our code: really nice gift from clojure.

But, as hack, for fast solution, i use next middleware:

(defn wrap-content-json [h]
  (fn [req] (assoc-in (h req) [:headers "Content-Type"] "application/json")))