clojure liberator - returning json from a put request

893 views Asked by At

I am struggling to return JSON from a put! request:

My code looks like this:

(defn body-as-string [ctx]
  (if-let [body (get-in ctx [:request :body])]
    (condp instance? body
      java.lang.String body
      (slurp (io/reader body)))))

(defn orbit-world [dimensions ctx]
  (let [in (json/parse-string (body-as-string ctx))]
    (json/generate-string in)))

(defn init-world [params]
  (let [dimensions (Integer/parseInt params)
     world (vec (repeat dimensions (vec (take dimensions (repeatedly #(rand-int 2))))))]
    (json/generate-string world)))

(defresource world [dimensions]
  :allowed-methods [:get :put]
  :available-media-types ["application/json"]
  :available-charsets ["utf-8"]
  :handle-ok (fn [_] (init-world dimensions))
  :put! (fn [ctx] (orbit-world dimensions ctx)))

I simply want to return anything that is passed to the put request back as JSON until I understand what is going on.

But if I make a put request, I get the following response:

HTTP/1.1 201 Created

Date: Sun, 18 May 2014 15:35:32 GMT

Content-Type: text/plain

Content-Length: 0

Server: Jetty(7.6.8.v20121106)

My GET request returns JSON so I don't understand why the PUT request is not/

1

There are 1 answers

1
Faris Nasution On BEST ANSWER

That is because a successfull PUT request does not return a http 200 status code (at least according to liberator), it returns a http 201 status code, as you can see from the response. Liberator handle http status code each in a different handler. In order to achieve what you want, you have to do:

(defresource world [dimensions]
  :allowed-methods [:get :put]
  :available-media-types ["application/json"]
  :available-charsets ["utf-8"]
  :handle-ok (fn [_] (init-world dimensions))
  :put! (fn [ctx] (orbit-world dimensions ctx))
  :handle-created (fn [_] (init-world dimensions))) ; Basically just a handler like any other.

Since you declare none on :handle-created, it defaults to an empty string with a text/plain content-type.

Edit:

In order to understand more, you have to see the decision graph. In there, you can see that after handling put! it goes to decision handling new?, if it's true go to handle-created if false, go to respond-with-entity? and so on.