我们如何在Clojure中制作Web应用程序?

时间:2020-03-06 15:04:46  来源:igfitidea点击:

我想这对于每天使用Java的绝大多数程序员来说是一个奇怪的问题。我不。我知道Java语言,因为我从事过Java项目,但不从事Java世界。我从来没有用Java从头开始制作一个Web应用程序。如果必须使用Python,Ruby进行操作,我知道应该去哪里(Django或者Rails),但是如果我想在Clojure中创建Web应用程序,不是因为我被迫生活在Java世界中,而是因为我喜欢这种语言,我想尝试一下,我应该使用哪些库和框架?

解决方案

到目前为止,我尚未遇到的最好的Clojure Web框架是Compojure:http://github.com/weavejester/compojure/tree/master

它虽然小巧但功能强大,并且语法优美。 (它在后台使用Jetty,但是除非我们愿意,否则它会向我们隐藏Servlet API,这种情况很少见)。在该URL上查看README,然后下载快照并开始播放。

Webjure,Clojure的Web编程框架。

功能:调度Servlet调用Clojure函数。动态HTML生成。 SQL查询接口(通过JDBC)。

此答案旨在作为Webjure信息的占位符。

Compojure是我用来构建小型博客应用程序的工具。它以Sinatra为模型,Sinatra是用于Ruby的最小,轻量级的Web框架。我主要只是使用路由,就像Sinatra一样。看起来像:

(GET "/post/:id/:slug"
  (some-function-that-returns-html :id :slug))

没有ORM或者模板库,但是它确实具有将向量转换为HTML的功能。

Compojure不再是用于开发Web应用程序的完整框架。自0.4版本以来,compojure已分解为多个项目。
通过抽象HTTP请求和响应过程,Ring提供了基础。 Ring将解析传入的请求,并生成一个包含请求的所有部分(例如uri,服务器名和请求方法)的映射。然后,应用程序将处理该请求,并根据该请求生成响应。响应表示为包含以下键的映射:状态,标头和正文。因此,一个简单的应用程序将如下所示:

(def app [req]
  (if (= "/home" (:uri req))
    {:status 200
     :body "<h3>Welcome Home</h3>"}
    {:status 200 
     :body "<a href='/home'>Go Home!</a>"}))

Ring的另一部分是中间件的概念。这是位于处理程序与传入请求和/或者传出响应之间的代码。一些内置的中间件包括会话和stacktrace。会话中间件将在请求映射中添加:session密钥,该密钥包含发出请求的用户的所有会话信息。如果:session密钥出现在响应映射中,它将被存储以供当前用户的下一个请求使用。尽管堆栈跟踪中间件将捕获在处理请求时发生的任何异常,并生成堆栈跟踪,如果确实发生任何异常,则将其作为响应发送回去。

直接使用Ring可能很乏味,因此Compojure建立在Ring的基础上,抽象出了细节。现在可以用路由来表示应用程序,因此我们可以拥有以下内容:

(defroutes my-routes
  (GET "/" [] "<h1>Hello all!</h1>")
  (GET "/user/:id" [id] (str "<h1>Hello " id "</h1>")))

Compojure仍在使用请求/响应映射,因此我们可以根据需要随时访问它们:

(defroutes my-routes
  (GET "*" {uri :uri} 
           {:staus 200 :body (str "The uri of the current page is: " uri)}))

在这种情况下,{uri:uri}部分访问请求映射中的:uri键,并将uri设置为该值。

最后一个组件是打ic,它使生成html更容易。各种html标签用矢量表示,第一个元素代表标签名称,其余元素代表标签的主体。 " &lt;h2>标题&lt;/ h2>"成为[:h2"标题"]。标签的属性在可选映射中。 "" &lt;a href='/login'>登录页面&lt;/a>"变为[[:a {:href" / login"}"登录页面"]`。这是一个使用模板生成html的小示例。

(defn layout [title & body]
  (html
    [:head [:title title]]
    [:body [:h1.header title] body])) 

(defn say-hello [name]
  (layout "Welcome Page" [:h3 (str "Hello " name)]))

(defn hiccup-routes
  (GET "/user/:name" [name] (say-hello name)))

这是指向compojure作者当前正在编写的一些文档的草稿的链接,我们可能会发现有帮助:Compojure Doc