リングとAppengine-Magicのハンドラーを理解する(Clojure)
-
11-10-2019 - |
質問
Clojure Webアプリの作業を開始し、Ring + Compojureの組み合わせを使用することにしました。最近、Appengine-magic(https://github.com/gcv/appengine-magic)を使用してGoogle Appengineを試すことにしました。ただし、Appengine-Magic(開始関数を介して)とRingのRun-Jetty関数の両方がパラメーターとして1つのハンドラーのみを取得しているため、いくつかのハンドラーを実装しており、それらをすべて展開する方法を知りたいと思います。
よろしくお願いします、ze
解決
常に1つのトップレベルのハンドラーしか存在しません。結局のところ、概念的なレベルで複数のハンドラーがある場合でも、アプリは特定のリクエストに適用するものを決定する必要があるため、選択をするルーチンはトップレベルのハンドラー。したがって、簡単な答えは、リクエストを調べて、アプリ内の複数のハンドラーの中の適切なハンドラーに引き渡す関数を提供する必要があるということです。その関数は、指定されるハンドラーです run-jetty
(または同等)。
通常、Ring + Compojureを使用すると、特定のURIといくつかの特別な目的のハンドラー(たとえば、404Sなど)をミドルウェアとして実装するための基本的な(「内部」)ハンドラーがあります。前者はで定義される傾向があります defroutes
フォーム、後者は高次関数です。
ミドルウェアハンドラーは、リクエストを見た後、すぐに応答を返すか、包み込まれているハンドラーに委任するかどうかを自分で決定します。ルートベースの「内側」ハンドラーは、適切なurisを求められており、返却するオプションがあります nil
リクエストが彼らに意味がないことを示すために(その時点で、残りのルートベースのハンドラーは試されます。すべてが nil
最終的な応答は通常、いくつかのミドルウェアによって生成され、おそらく404を返す可能性があります。
Compojureに関して長い答えを書きました ここ;おそらく、Compojureのルートベースのハンドラー定義を把握するのに役立つかもしれません。
他のヒント
これが最良のアプローチであるかどうかはわかりません。最終的には、他のハンドラーをメインのハンドラーにラップするring.middleware関数を実装することになりました。
(defn wrap-ohandler [f handler]
(fn [req]
(let [ res (f req) ]
(if (= res nil) (handler req) res))))
(def handler-wrapped
(-> #'main-handler
(wrap-ohandler #'anotherhandler )
(wrap-stacktrace)
(wrap-params)))
これは機能しますが、これは良いアプローチですか?