成熟的Clojure Web框架?

48

目前成熟的Clojure Web框架有哪些选择?我希望能得到一种功能矩阵,告诉我流行框架支持什么程度的功能,包括:

  • 响应模板(响应以Clojure或其他标记语言编写 -例如类似于具有Tiles的JSP)
  • HTTP会话
  • REST自动映射URL到操作函数和参数
  • HTML表单(参数可用作映射,错误处理,验证)
  • 应用程序流程(来自Java框架 -请求处理程序返回最终由渲染器处理的操作标识符)

-1 表示请求 HTTP 会话,但 Play 框架证明你不需要它。 - Peter Hilton
5个回答

33

或许我在SO上回答的“Clojure开发RESTful Web服务的好起点是什么?”问题的答案可以帮到你。它提到了一些重要的Clojure Web库(附有链接和简短概述)。我想在这里重申的关键点在于该回答的第一段:

首先,我认为你不太可能找到一个单一的解决方案来处理所有这些问题(除非通过interop使用Java库的形式)。正在成为Clojure标准Web堆栈的是由多个库组成的,人们可以以各种方式混合和匹配(因为它们通常是完全兼容的)。

此外,我会补充说,你可能不应该期望使用类似于Java的“应用程序流程”来处理事务(如果你确实需要,你可能需要自己编写支持它的库!)。但没关系,因为人们似乎非常喜欢Ring的“处理程序是函数”,高阶中间件友好的方法。


回答您的问题:

  • 响应模板:
    有许多Clojure特定的解决方案,包括EnliveHiccup(Enlive是一个非常强大的HTML抓取/模板/转换引擎;Hiccup是用Clojure编写HTML的DSL,具有渲染快速的优点)。此外,这可能是一个完美的地方,可以转到Java并使用类似StringTemplate的东西。这甚至有一个好的副作用,防止了模板和逻辑混合!(我相信Stuart Halloway已经提到过Relevance-他的公司-正在使用这种策略,并且取得了巨大的成功。)

  • HTTP会话
    那应该是Sandbar。作者已经开始发布了一系列博客文章,看起来非常有前途。

  • 自动将URL映射到操作函数和参数的REST
    那就是RingCompojure和/或Moustache。见下文。

  • HTML表单(可用作map的参数,错误处理,验证)
    如上所述。

  • 应用程序流程(从Java框架中知道-请求处理程序返回最终由渲染器处理的操作标识符)
    如上所述,这不是人们倾向于在Clojure中做的事情。


作为学习Clojure网络堆栈的起点,Ring的作者Mark McGranaghan编写的这个Ring教程非常有帮助。Compojure的作者James Reeves在Compojure上有一些文档。也许我最近回答的关于Compojure路由背后的“大思想”是什么?的问题也会有所帮助。Ring的源代码还包括一个很棒的SPEC文档。

1
请问您能否详细解释一下模板选项的问题,并解释一下为什么建议"转向Java"?这是否与功能的成熟度、性能或其他方面有关? - Rob Lachlan
@Rob Lachlan:我不一定会建议转向Java - 我只是认为在这种任务中这样做未必会导致劣质的体验。如果你构建应用程序,使得模板引擎在呈现阶段从不调用应用程序逻辑,那么它是用Java / Scala /任何什么语言编写的又有什么区别呢?当然,只要有一种合理的方法来设置模板变量(例如,StringTemplate在模板上使用.setAttribute,这足够简单,可以与Clojure中的doseq和映射一起使用)。 - Michał Marczyk
这并不是说没有理由更喜欢纯Clojure模板方案 - 例如,我不确定是否有任何类似于Enlive的东西存在于Clojure领域之外(但是创造奇迹需要时间,因此在某些情况下选择更简单的解决方案可能更合适),Hiccup是一个很棒的HTML生成DSL(但是教设计师编写Hiccup是否有多大意义,当他们已经知道另一个JVM解决方案,你可以直接调用它?)等。 - Michał Marczyk
我认为在这个特定问题的情况下,如果OP习惯于使用Java进行Web开发,那么他可能对他通常使用的任何JVM模板引擎感到非常满意。此外,我真的想不出Clojure中StringTemplate的直接等价物(也看不出发明它的理由),它似乎是HTML模板化的一个绝佳解决方案。 - Michał Marczyk
非常感谢您提出的这些好建议。这让我对问题有了更清晰的认识,我得出结论,对于我的个人项目,我将使用直接的hiccup。毕竟,我们的编程语言的语法形式与XML和HTML是同构的(或者非常接近),因此利用这一事实似乎是一件值得的事情。 - Rob Lachlan
我为Clojure制作了一个全栈框架:coast on clojure。它还很年轻,这就是为什么我留下了评论而不是答案,因为它在技术上还不够成熟(在其他全栈框架表现出色的几个领域仍然存在缺陷)。看看它是否解决了问题! - swlkr

14
自从最初提问/回答此问题时,已经出现了一个有前途的解决方案——Noir web框架
它使用hiccup进行模板处理,但在此基础上提供了一个更为完整的框架。
以下是Noir主页上的基本代码示例:
(ns my-app
  (:use noir.core)
  (:require [noir.server :as server]))

(defpage "/welcome" []
    "Welcome to Noir!")

(server/start 8080)

1
Noir现已被弃用(http://www.webnoir.org/),但请参见lib-noir(https://github.com/noir-clojure/lib-noir)。 - Gordon Gustafson

8
我建议您使用Luminus,不仅因为它的棒名字,还因为它的功能。
由于Noir不再得到维护,我不建议您使用它。从最开始使用ring和Compojure来构建自己的框架也是一个不错的选择。

1

尝试使用Road框架进行快速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}))

1
您可能问错了问题。我在您的问题中看到的是"哪个Clojure框架最像我所熟悉的Java面向对象框架?"。 对此没有好的答案;如果您只对类似Grails或Tapestry这样的有状态服务器端方法感到舒适,那么可能应该留在原地,并找到一种在Clojure中实现后端的方法。
另一方面,如果您想构建更符合Clojure的东西,您可能想要找到自己的组合。我在客户端使用AngularJS和CoffeeScript取得了一些良好的成功,而在服务器端使用Clojure(使用Ring和Bishop)(尽管我们正在从Bishop转移到Liberator)。无论如何,一旦您接受“单页面”Web应用程序方法并开始将服务器端视为数据源和数据汇,您会发现Clojure非常出色。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接