我开始开发一些 clojure 网络应用程序,并决定使用 Ring + Compojure 的组合。最近我决定用 AppEngine-magic (https://github.com/gcv/appengine-magic) 试试 Google Appengine。然而,appengine-magic(通过它的 start 函数)和 ring 的 run-jetty 函数都只需要 1 个处理程序作为参数,我正在实现几个处理程序并想知道如何部署它们。
提前致谢,泽
我开始开发一些 clojure 网络应用程序,并决定使用 Ring + Compojure 的组合。最近我决定用 AppEngine-magic (https://github.com/gcv/appengine-magic) 试试 Google Appengine。然而,appengine-magic(通过它的 start 函数)和 ring 的 run-jetty 函数都只需要 1 个处理程序作为参数,我正在实现几个处理程序并想知道如何部署它们。
提前致谢,泽
总是只有一个顶级处理程序——毕竟,即使在某个概念级别有多个处理程序,应用程序也需要决定以某种方式将哪个处理程序应用于给定请求,因此做出选择的例程变为顶级处理程序。因此,简短的回答是您需要提供一个函数来查看请求并将其交给应用程序内的多个处理程序中的适当处理程序;该函数是要提供给run-jetty
(或等效)的处理程序。
通常使用 Ring + Compojure,您将拥有一些用于处理特定 URI 的基本(“内部”)处理程序和一些作为中间件实现的特殊用途处理程序(例如,用于 404)。前者倾向于以defroutes
形式定义,而后者是高阶函数。
中间件处理程序自行决定——在查看请求后——他们是想立即返回响应还是委托给它们所包裹的处理程序。基于路由的“内部”处理程序被调用以获取适当的 URI,并且可以选择返回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)))
这行得通,但这是一个好方法吗?