Skip to content

Instantly share code, notes, and snippets.

@cemerick
Created September 6, 2012 16:07
Show Gist options
  • Save cemerick/3657912 to your computer and use it in GitHub Desktop.
Save cemerick/3657912 to your computer and use it in GitHub Desktop.
#{Ring, Compojure}-friendly shoreleave-remote backend
;;; this is now in a library: https://github.com/cemerick/shoreleave-remote-ring
(ns ^{:doc "Server-side RPC support for use with shoreleave (and maybe fetch?).
Mostly copied from https://github.com/shoreleave/shoreleave-remote-noir;
changed to eliminate the noir-isms..."}
cemerick.cljs.rpc)
(def default-remote-uri "/_fetch")
(def remotes (atom {}))
(defn add-remote [key func]
(swap! remotes assoc key func))
(defn safe-read [s]
;; can we please have a civilization!?
(binding [*read-eval* false]
(read-string s)))
(defmacro defremote
"Same as defn, but also registers the defined function as a remote.
The name of the remote is the same as the function's name by default;
You can optionally specify a different name by adding :remote-name
metadata to the function name, e.g.:
(defremote ^{:remote-name :your-fn} my-fn [] ...)"
[& [name :as body]]
`(do
(defn ~@body)
(add-remote
(keyword (name (or (-> (var ~name) meta :remote-name)
~name)))
~name)
(var ~name)))
(defn call-remote
[remote-key params]
(if-let [func (@remotes remote-key)]
(let [result (apply func params)]
{:status 202
:headers {"Content-Type" "application/clojure; charset=utf-8"}
:body (pr-str result)})
{:status 404}))
(defn handle-rpc
[{{:keys [params remote]} :params :as request}]
(call-remote (keyword remote) (safe-read params)))
(defn wrap-rpc
([app] (wrap-rpc app default-remote-uri))
([app remote-uri]
(fn [{:keys [request-method uri] :as request}]
(if (and (= :post request-method) (= remote-uri uri))
(handle-rpc request)
(app request)))))
@ohpauleez
Copy link

Solid work Chas. I'll integrate new code this weekend. I really appreciate you digging through this.

@robert-stuttaford
Copy link

Awesome!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment