成熟的Clojure网页框架?
成熟的Clojure Web框架目前有哪些select? 我正在寻找一些functionmatrix,告诉我什么是stream行的框架支持和什么程度,包括:
- 响应模板(以Clojure或其他标记写的响应 – 例如像带有Tiles的JSP)
- HTTP会话
- REST自动将URL映射到动作函数和参数中
- HTML表单(params可用作地图,error handling,validation)
- 应用程序stream程(从Java框架知道 – 请求处理程序返回最终由渲染器处理的动作标识符)
也许我对Clojure开发REST风格的Web服务有什么好的起点? 关于SO的问题可能对你有帮助。 它提到了一些重要的Clojurenetworking库(带有链接和简短摘要)。 答复的第一段说明了我想在此重申的关键点:
首先,我认为你不可能在Clojure中find一个简单的解包scheme(除了通过互操作使用Java库)。 什么是成为Clojure的标准Web栈包括一些人们以各种方式混合和匹配(因为他们愉快地倾向于完全兼容)的图书馆。
为此我补充一点,你可能不应该期望用Java可能知道的那种“应用程序stream”来处理事情(或者如果你确实需要它,你可能不得不推出自己的lib来支持它!)。 不过,没关系,人们似乎对Ring的处理函数,高阶中间件友好的方法感到非常满意。
为了解决你的子弹:
-
响应模板:
有许多Clojure特定的解决scheme,包括Enlive和Hiccup (Enlive是一个非常强大的HTML抓取/模板/转换引擎; Hiccup是用于在Clojure中编写HTML的一个DSL,具有很好的渲染速度 )。 此外,这可能是一个地方,下降到Java和使用像StringTemplate类似的东西是完全合理的 。 这甚至有阻止混合模板和逻辑的好方面! (我相信Stuart Halloway曾经提到Relevance – 他的公司 – 在他们的工作中使用这个策略,并取得了巨大的成功。) -
HTTP会话
我想这将是桑德巴尔 。 作者已经开始了一系列看起来很有希望的博客文章。 -
REST自动将URL映射到动作函数和参数中
这是环和Compojure和/或胡子 。 见下文。 -
HTML表单(params可用作地图,error handling,validation)
如上。 -
应用程序stream程(从Java框架知道 – 请求处理程序返回最终由渲染器处理的动作标识符)
如上所述,在Clojure中并不是人们倾向于做的事情。
作为学习Clojure web堆栈的起点, Ring的作者Mark McGranaghan的Ring教程非常有帮助。 Compojure的作者James Reeves在Compojure上有一些文档 。 也许我最近的答案是什么是组合路线背后的“大创意”? 问题可能也有帮助。 Ring的来源还包括一个很好的SPEC文档。
由于这个问题最初是被问及/回答的, Noirnetworking框架已经成为一个有希望的解决scheme。
它使用模板部分的打嗝,但提供了一个更完整的框架。
Noir主页的基本代码示例:
(ns my-app (:use noir.core) (:require [noir.server :as server])) (defpage "/welcome" [] "Welcome to Noir!") (server/start 8080)
我会推荐你使用Luminus ,不是因为它的真棒名称,而是它的function。
而且由于Noir不再维护,我不会推荐你使用它。 从一开始就从Ring&Compojure开始构build自己的框架也是一个不错的select。
你可能会问错误的问题。 我在你的问题中看到的是“Clojure框架最像我习惯的Java Object-Oriented框架?”。 对此没有很好的答案。 如果你只对服务器端方法(如Grails或Tapestry)感到满意,那么也许你应该呆在那里,并find一种在Clojure中实现你的后端的方法。
另一方面,如果你想build立更真实的Clojure,你可能想要find你自己的组合。 在客户端使用AngularJS和CoffeeScript,在服务器上使用Clojure(使用Ring和Bishop)(虽然我们正在从Bishop移动到Liberator),我取得了一些成功的成功。 在任何情况下,一旦你拥抱“单页”的networking应用程序的方法,并开始把服务器端作为数据源和接收器,你会发现Clojure工作得非常好。
尝试快速web开发道路框架https://github.com/zhujinxian/road
(defn render-test [ret tmt] (-> (resp/response "------render----test------") (#(resp/content-type %1 "text/plain")))) (defn foo "I don't do a whole lot." [x] (str "来自源码目录的参数:" x)) (defn handler [^Integer x] {:$r render-test :text (str "hello world, road goes sucess!" (foo x))}) (defn home [req content ^Integer num] {:hiccup "home.clj" :content (str "home" content) :num num}) (defroad road (GET "/web-test-0.1.0-SNAPSHOT-standalone/main" handler) (GET "/web-test-0.1.0-SNAPSHOT-standalone/home/:num{\\d+}" home)) (defn -main [& args] (log/info "---------log4j test-------") (jetty/run-jetty road {:port 3000}))