clojuremongerliberator

key delete! invoked when the method is PUT


I'm trying to build a simple rest api, using liberator and monger :

(ns tm.place.endpoint
  (:require [liberator.core :refer [defresource]]
            [monger [collection :as mc] [query :as mq]]
            [clojure.data [json :as json]]
            monger.json))

(defresource entity-place-resource [id]
  :available-media-types ["application/json"]
  :allowed-methods [:get :put :delete]
  :exists? (if-let [place (mc/find-map-by-id "place" id)] {:place place})
  :handle-ok :place
;  :handle-created (fn [ctx] 
;                     (let [body (-> ctx :request :body)]
;                       (assoc body :_id id)))
  :handle-not-found []
  :handle-not-acceptable "Should accept application/json"
  :handle-method-not-allowed (json/write-str 
                              {:message "Can only handle get, put and delete"})
;  :handle-not-implemented
;  :handle-no-content
  :put! (fn [ctx] 
          (let [body (-> ctx :request :body)]
            (mc/update-by-id "place" id (assoc body :_id id))))
  :delete! (mc/remove-by-id "place" id)
  :can-put-to-missing? false)

I'm using advanced rest client to see if it works. If the method is :get or :delete, it does perfectly what I want (It first check if a document is exists, and then do the appropriate action). However, if the method is :put, it simply spits out http 201 created, which I think the request is success, but the corresponding document is deleted, not updated.

If I comment out the :delete! line, the :put! is work as expected, so I'm guessing the culprit is the :delete! line, but I have no idea why because since I'm using :put method, I'm assuming :delete! should remain untouched. Any idea why?


Solution

  • As you have defined your delete! as a bare function it's going to get evaluated when you don't expect. The pattern you have followed for put! needs to be applied, where you return a fn that does the work rather than act directly.

    http://clojure-liberator.github.io/liberator/faq.html

    Due to the exact details of the defresource macro expansion, the form used as the value is evaluated at unexpected times.