成熟的 Clojure Web 框架?

发布于 2024-09-15 12:18:40 字数 1436 浏览 1 评论 0原文

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

回眸一笑 2024-09-22 12:18:41

也许我的回答 在 Clojure 中开发 RESTful Web 服务的良好起点是什么? 问题可能对您有帮助。它提到了 Clojure 的一些重要 Web 库(带有链接和简短摘要)。我想在这里重申的关键点已在该答案的第一段中阐明:

首先,我认为您不太可能找到一个单一的收缩解决方案来在 Clojure 中完成所有这些工作(除非以通过互操作使用的 Java 库的形式)。正在成为 Clojure 标准 Web 堆栈的内容包括许多库,人们以各种方式混合和匹配这些库(因为它们很高兴倾向于完美兼容)。

除此之外,我想补充一点,您可能不应该期望使用您可能从 Java 中了解的那种“应用程序流程”来处理事情(或者如果您认为您确实需要它,您可能必须推出自己的库来支持它) !)。不过,这没关系,因为人们似乎对 Ring 的处理程序即函数、高阶中间件友好的方法非常满意。


要解决您的问题:


作为学习 Clojure Web 堆栈的起点,此环Ring 作者 Mark McGranaghan 的教程非常有帮助。 Compojure 的作者 James Reeves 拥有 有关 Compojure 的一些文档。也许我最近对“什么是”的回答 compojure 路线背后的“大创意”? 问题也可能有帮助。 Ring 的来源还包括一份很棒的 SPEC 文档。

Perhaps my answer to the What is the good starting point to developing RESTful web service in Clojure? question on SO might be of help to you. It mentions some important web libraries for Clojure (with links and short summaries). The key point which I would like to reiterate here is stated in the first paragraph of that answer:

First of all, I think that you are unlikely to find a single shrinkwrapped solution to do all this in Clojure (except in the form of a Java library to be used through interop). What is becoming Clojure's standard Web stack comprises a number of libraries which people mix and match in all sorts of ways (since they happily tend to be perfectly compatible).

To that I would add that you should probably not expect to handle things with the sort of "application flow" you might know from Java (or if you believe you really need it, you'll probably have to roll your own lib to support it!). That's alright, though, as people seem to be very happy with Ring's handler-is-a-function, higher-order-middleware-friendly approach.


To address your bullets:

  • Response templating:
    There is a number of Clojure-specific solutions, including Enlive and Hiccup (Enlive is a very powerful HTML scraping / templating / transforming engine; Hiccup is a DSL for writing HTML in Clojure with the nice property that it renders fast). Also, this is probably one place where it makes perfect sense to drop down to Java and use something like, say, StringTemplate. This even has the good side of discouraging the mixing of templates and logic! (I believe Stuart Halloway has mentioned that Relevance -- his company -- is using this strategy in their work and having great success with it.)

  • HTTP sessions
    That would be Sandbar, I suppose. The author has started a series of blogposts about it which looks very promising.

  • REST with automatic mapping of URLs into action-functions and params
    That's Ring & Compojure and/or Moustache. See below.

  • HTML forms (params available as map, error handling, validation)
    As above.

  • Application flow (known from Java frameworks - request handlers return action identifiers which are eventually handled by renderers)
    As mentioned above, not really something people tend to do in Clojure.


As a starting point in learning about the Clojure web stack, this Ring tutorial by Ring's author Mark McGranaghan is very helpful. Compojure's author James Reeves has some documentation on Compojure. Perhaps my recent answer to the What’s the “big idea” behind compojure routes? question might be of help too. Ring's sources also include a great SPEC document.

掩饰不了的爱 2024-09-22 12:18:41

由于这个问题最初被提出/回答,Noir web 框架 已经成为一个有前途的解决方案。

它使用 hiccup 作为模板部分,但提供了一个更完整的框架。

Noir 主页的基本代码示例:

(ns my-app
  (:use noir.core)
  (:require [noir.server :as server]))

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

(server/start 8080)

Since this question was originally asked / answered, the Noir web framework has emerged as a promising solution.

It uses hiccup for the templating part, but offers a more complete framework around that.

Basic code sample from the Noir main page:

(ns my-app
  (:use noir.core)
  (:require [noir.server :as server]))

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

(server/start 8080)
∞琼窗梦回ˉ 2024-09-22 12:18:41

我会推荐你​​使用 Luminus,不是因为它的名字很棒,而是因为它的功能。

由于 Noir 不再维护,我不会建议您使用它。
从戒指入手也是不错的选择Compojure 从一开始就构建自己的框架。

I will recommend you to use Luminus, not because of its awesome name, but also its feature.

And since Noir is no longer maintained, I won't recommend you to use that.
It is also a good choice to start from ring & Compojure from the very beginning to build your own framework.

执笔绘流年 2024-09-22 12:18:41

你可能问错了问题。我在你的问题中看到的是“哪个 Clojure 框架最像我习惯的 Java 面向对象框架?”。对此没有好的答案;如果您只对有状态的服务器端方法(例如 Grails 或 Tapestry)感到满意,那么也许您应该留在那里,并找到一种在 Clojure 中实现某些后端的方法。

另一方面,如果您想构建更符合 Clojure 的东西,您可能需要找到自己的组合。我在客户端上使用 AngularJS 和 CoffeeScript,在服务器上使用 Clojure(使用 Ring 和 Bishop)取得了一些良好的成功(尽管我们正在从 Bishop 转向 Liberator)。无论如何,一旦您采用“单页”Web 应用程序方法并开始将服务器端视为数据源和数据接收器,您就会发现 Clojure 工作得非常好。

You may be asking the wrong question. What I'm seeing in your question is "what Clojure framework is most like the Java Object-Oriented frameworks I'm used to?". There is no good answer to that; if you only feel comfortable with a state-ful server-side approach (such as Grails or Tapestry) then perhaps you should stay there, and find a way to implement some of your backend in Clojure.

On the other hand, if you want to build something more true to Clojure, you may want to find your own mix. I've had some good success using AngularJS and CoffeeScript on the client, and Clojure (using Ring and Bishop) on the server (though we are moving from Bishop to Liberator). In any case, once you embrace the "single page" web app approach and start treating the server-side as a source and sink of data, you'll find Clojure works exceptionally well.

小姐丶请自重 2024-09-22 12:18:41

尝试快速 Web 开发的 Road 框架 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}))

try road framework for fast web dev 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}))
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文