2012-04-19

Migrate "REST" to Clojure 1.3.0 with Slingshot

I'm really inspired by Mark McGranaghan's Building REST APIs for Clojure Web Applications. It uses Clojure 1.2.0, but I'm really fancy at new things and wanted to port the code to Clojure 1.3.0. I learned that clojure.contrib is no longer in use and clojure.contrib.condition is now replaced by Steve Gilardi's Slingshot. So I hacked a bit ... I'm not sure if my codes are good enough. Comments are more than welcome. Changes in web.clj:
  (:use [compojure.core]
        [ring.middleware.json-params]
        [slingshot.slingshot :only [try+]])
; ...
(defn wrap-error-handling [handler]
  (fn [req]
      (try+
       (or (handler req)
           (json-response {"error" "resource not found"} 404))
       (catch JsonParseException e
              (json-response {"error" "malformed json"} 400))
       (catch [:type :bad-req] {:keys [reason message]}
              (json-response {"error" message} (error-codes reason))))))
Changes in elem.clj
  (:use [slingshot.slingshot :only [throw+]])
; ...
(defn get [id]
  (or (@elems id)
      (throw+ {:type :bad-req :reason :not-found
              :message (format "elem '%s' not found" id)})))

(defn put [id attrs]
  (if (empty? attrs)
      (throw+ {:type :bad-req :reason :invalid
              :message "attrs are empty"})
; ...
And it passes test.sh: (Sorry! I don't know how to write lein test cases.)
{}
{"error":"elem '1' not found"}
{"group":"bar"}
{"group":"biz","tag":"bat"}
{"group":"bar"}
{"2":{"group":"biz","tag":"bat"}}
{"error":"elem '3' not found"}
{"error":"resource not found"}
{"error":"malformed json"}400
{"error":"elem '3' not found"}404
{"error":"attrs are empty"}400
You may download the example here.

沒有留言: