Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

clojure liberator - returning json from a put request

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/

like image 521
dagda1 Avatar asked May 18 '14 15:05

dagda1


1 Answers

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.

like image 109
Faris Nasution Avatar answered Sep 23 '22 03:09

Faris Nasution