clojure liberator - returning json from a put request
Asked Answered
B

1

6

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/

Bugs answered 18/5, 2014 at 15:45 Comment(0)
C
6

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.

Cool answered 18/5, 2014 at 17:7 Comment(1)
It can really help to add the Liberator wrap-trace middleware. You will then get X-Liberator headers in the responses which show the state of liberator at various decision points. It also shows you which handler was used. In this case, it would show that the default handle-created was being used.Sorn

© 2022 - 2024 — McMap. All rights reserved.