私は ClojureScript アプリケーションを持っていて、クライアント側での通常の関数 core.async 呼び出しのように見えるサーバーへの RPC 呼び出しを行いたいと考えています。
とりあえずこれを行うために、cljx に基づいて以下のコードを書きました。RPC 定義セクションでは、RPC としてクライアント側に公開したいすべてのサーバー側関数を追加する必要があります。
注: send 関数はここから取得されます: https://dimagog.github.io/blog/clojure/clojurescript/2013/07/12/making-http-requests-from-clojurescript-with-core.async/
定型コードなしでこれをよりうまく行う方法はありますか?
私が持っている唯一のアイデアは、RPCに必要なサーバー側とクライアント側のコードを生成するleiningenプラグインを作成することです。つまり、cljxを使用して現時点で行っている部分です。より良い方法はありますか?
(ns myapp.shared.rpc
(:require
#+cljs [myapp.tools :refer [send log]]
#+cljs [cljs.reader :as reader]
#+clj [clojure.tools.logging :as log]
#+clj [noir.response :refer [edn]]
#+clj [myapp.rpc :as rpc]
))
#+cljs (defn rpc-client [function params]
#+cljs (log "RPC call: (" function params ")")
#+cljs (send "POST" "/api"
#+cljs (str "rpc=" (pr-str {:fun function :params params}))
#+cljs (fn [x]
#+cljs (log "RPC response:'" x "'")
#+cljs (:response (reader/read-string x)))))
#+clj (defmulti rpc-impl #(:fun %))
#+clj (defn rpc-server [{rpc :rpc}]
#+clj (log/info "RPC call received:" rpc)
#+clj (let [response (-> rpc read-string rpc-impl)]
#+clj (log/info "RPC response sent: '" response "'")
#+clj (edn {:response response})))
;;;;; RPC definitions
#+cljs (defn demo [ & p] (rpc-client :demo p))
#+clj (defmethod rpc-impl :demo [{p :params}] (apply rpc/demo p))