标签: compojure

组合路线背后的"大创意"是什么?

我是Clojure的新手,并且一直在使用Compojure编写基本的Web应用程序.不过,我正在用Compojure的defroutes语法碰壁,我认为我需要理解它背后的"如何"和"为什么".

看起来像Ring样式的应用程序以HTTP请求映射开始,然后只是通过一系列中间件函数传递请求,直到它被转换为响应映射,然后将其发送回浏览器.对于开发人员来说,这种风格似乎太"低级",因此需要像Compojure这样的工具.我可以看到在其他软件生态系统中需要更多的抽象,尤其是Python的WSGI.

问题是我不了解Compojure的方法.我们采用以下defroutesS表达式:

(defroutes main-routes
  (GET "/"  [] (workbench))
  (POST "/save" {form-params :form-params} (str form-params))
  (GET "/test" [& more] (str "<pre>" more "</pre>"))
  (GET ["/:filename" :filename #".*"] [filename]
    (response/file-response filename {:root "./static"}))
  (ANY "*"  [] "<h1>Page not found.</h1>"))
Run Code Online (Sandbox Code Playgroud)

我知道理解所有这些的关键在于一些宏观伏都教,但我还没有完全理解宏(还).我已经盯着defroutes源头很长一段时间了,但就是不明白!这里发生了什么?理解"大创意"可能会帮助我回答这些具体问题:

  1. 如何从路由功能(例如workbench功能)中访问Ring环境?例如,假设我想访问HTTP_ACCEPT标头或请求/中间件的其他部分?
  2. 什么是解构({form-params :form-params})?在解构时我可以使用哪些关键字?

我真的很喜欢Clojure,但我很难过!

clojure compojure

107
推荐指数
2
解决办法
2万
查看次数

如何在Apache中集成Clojure Web应用程序

注意

鉴于此OP大约两年前编写,而不是再次提出相同的问题,我想知道是否存在分步说明,以便我可以将Noir或其他Clojure Web应用程序集成到Apache中,无论是Jetty,Tomcat , 或者是其他东西.Django也存在类似的指令,我想我明白Python在Django的情况下是作为引擎而不是环形框架运行的,所以Clojure Web应用程序更复杂.

结束注释

我深深爱上了Clojure,而Compojure似乎是一个整洁的Web框架.

但是当我想将我的应用程序部署在像Tomcat这样的常规应用程序服务器上作为WAR时,它就崩溃了.我实际上必须为静态文件和资源编写自定义Ring处理程序,这些文件和资源可以在本地Jetty和Tomcat上运行,因为库存处理程序没有,我不得不手动将上下文根添加到任何地方.

令我感到非常惊讶的是,我必须编写所有这些代码来创建可以在Jetty和Tomcat上运行的最简单的Web应用程序.我只有三种可能的解释:

  1. 除了使用Jetty进行本地开发之外,没有人使用Clojure/Compojure,即在生产中
  2. 每个人都在没有上下文根的专用Jetty上部署Clojure/Compojure应用程序(LIke人们使用Node.js应用程序)
  3. 有一种非常简单的方法来规避我遇到的问题,我不知道

您认为以下哪一种情况?或者是别的什么?

编辑:

请注意,创建一个战争文件是Maven/Leiningen的明智之举,而不是我的意思.我想知道我必须编写如此多的代码来使Compojure与Tomcat一起工作,基本的东西,如静态文件服务和上下文根知识应该开箱即用.

deployment clojure war compojure

57
推荐指数
3
解决办法
1万
查看次数

具有不同中间件的Compojure路由

我目前正在使用Compojure(以及Ring和相关的中间件)在Clojure中编写API.

我正在尝试根据路由应用不同的身份验证代码.请考虑以下代码:

(defroutes public-routes
  (GET "/public-endpoint" [] ("PUBLIC ENDPOINT")))

(defroutes user-routes
  (GET "/user-endpoint1" [] ("USER ENDPOINT 1"))
  (GET "/user-endpoint2" [] ("USER ENDPOINT 1")))

(defroutes admin-routes
  (GET "/admin-endpoint" [] ("ADMIN ENDPOINT")))

(def app
  (handler/api
    (routes
      public-routes
      (-> user-routes
          (wrap-basic-authentication user-auth?)))))
      (-> admin-routes
          (wrap-basic-authentication admin-auth?)))))
Run Code Online (Sandbox Code Playgroud)

这不能按预期工作,因为它wrap-basic-authentication实际上包装了路由,因此无论包装路由如何都会尝试它.具体来说,如果需要将请求路由到admin-routes,user-auth?仍将尝试(并失败).

我使出context在一个共同的基本路径部分航线,但它是一个相当的限制(下面的代码可能无法正常工作,它只是说明的想法):

(defroutes user-routes
  (GET "-endpoint1" [] ("USER ENDPOINT 1"))
  (GET "-endpoint2" [] ("USER ENDPOINT 1")))

(defroutes admin-routes
  (GET "-endpoint" [] ("ADMIN ENDPOINT")))

(def app
  (handler/api
    (routes …
Run Code Online (Sandbox Code Playgroud)

middleware routes clojure compojure ring

38
推荐指数
3
解决办法
8599
查看次数

没有重新启动Web服务器的Compojure开发

我之前在Clojure中编写了一个小型Swing应用程序,现在我想创建一个Ajax风格的Web应用程序.Compojure现在看起来是最好的选择,所以这就是我要尝试的.

我想要一个真正的小编辑/尝试反馈循环,所以我不希望在每次小改变后重启web服务器.

实现这一目标的最佳方法是什么?默认情况下,我的Compojure设置(使用带有Jetty的ant deps/ant的标准内容)似乎没有重新加载我所做的任何更改.我将不得不重新启动run-server来查看更改.由于Java遗产和系统启动的方式等.这可能是完全正常的,当我从命令行启动系统时应该是这样.

但是,必须有一种方法可以在服务器运行时动态地重新加载内容.我应该使用REPL的Compojure来实现我的目标吗?如果我应该,我怎么重新加载我的东西?

clojure compojure

36
推荐指数
5
解决办法
1万
查看次数

在Compojure中默认为/默认提供index.html

我有一个静态文件index.html,我想在有人请求时提供服务/.通常,Web服务器默认执行此操作,但Compojure不这样做.index.html当有人请求时,我如何让Compojure服务/

这是我用于静态目录的代码:

; match anything in the static dir at resources/public
(route/resources "/")
Run Code Online (Sandbox Code Playgroud)

clojure compojure

32
推荐指数
5
解决办法
1万
查看次数

如何在Clojure中编写多语言应用程序?

我正在试图找出如何创建一个具有多语言支持的基于Compojure的网站.有没有像i18n这样的解决方案?

multilingual clojure internationalization compojure

23
推荐指数
3
解决办法
2309
查看次数

如何从clojure中的关系数据库中获取一个_model_数据?

我已经在twitter和#clojure IRC频道上提出了这个问题,但没有得到任何答复.

有几篇关于Clojure-for-Ruby程序员,Clojure-for-lisp程序员的文章......但缺少的部分是Clojure for ActiveRecord程序员.

有关于与MongoDB,Redis等进行交互的文章 - 但这些都是一天结束时的关键价值商店.但是,来自Rails背景,我们习惯于在继承方面考虑数据库 - has_many,polymorphic,belongs_to等.

关于Clojure/Compojure + MySQL(ffclassic)的几篇文章- 深入研究sql.当然,ORM可能导致阻抗不匹配,但事实仍然是,在像ActiveRecord一样思考之后,很难以其他方式思考.

我相信关系数据库非常适合面向对象的范例,因为它们本质上就是集合.像activerecord这样的东西非常适合建模这些数据.对于例如博客 - 简单地说

class Post < ActiveRecord::Base
  has_many :comments
 end


 class Comment < ActiveRecord::Base
   belongs_to :post
 end
Run Code Online (Sandbox Code Playgroud)

如何在Clojure中对此进行建模 - 这是如此严格的反OO?如果提到所有函数式编程语言,问题可能会更好,但我更感兴趣的是Clojure的观点(以及Clojure示例)

mysql postgresql functional-programming clojure compojure

20
推荐指数
2
解决办法
1958
查看次数

无法在Clojure中完成POST请求

我最近开始探索Clojure,我想建立一个具有基本CRUD功能的简单Web应用程序.我在这里找到了一个很好的教程:http://www.xuan-wu.com/2013-09-21-Basic-Web-Application-in-Clojure.

GET请求工作正常,但每当我尝试发布请求时,都会收到以下错误:

Invalid anti-forgery token
Run Code Online (Sandbox Code Playgroud)

我之前提到的教程没有涉及任何安全相关的问题.我做了一些挖掘,似乎我错过了Compojure的一些组件,它应该生成一个用于发出POST请求的令牌.有些地方提到我应该自动发生,而我没有任何改变.我仍然不确定我失踪了什么.这是我的代码:

(ns myblog.handler
    (:require [compojure.core :refer :all]
            [compojure.route :as route]
            [ring.middleware.defaults :refer [wrap-defaults site-defaults]]
            [myblog.views :as views]
            [myblog.posts :as posts]
            [ring.util.response :as resp]
            [ring.middleware.basic-authentication :refer :all]))

(defn authenticated? [name pass]
  (and (= name "user")
       (= pass "pass")))

(defroutes public-routes
    (GET "/" [] (views/main-page))
    (route/resources "/"))

(defroutes protected-routes
    (GET "/admin" [] (views/admin-page))
    (GET "/admin/add" [] (views/add-post))
    (POST "/admin/create" [& params]
        (do (posts/create params)
            (resp/redirect "/admin"))))

(defroutes app-routes
    public-routes
    (wrap-basic-authentication protected-routes authenticated?)
    (route/not-found …
Run Code Online (Sandbox Code Playgroud)

post clojure compojure antiforgerytoken

20
推荐指数
2
解决办法
3667
查看次数

noir vs compojure?

我无法理解clojure的Noir库.它似乎是一个在compojure之上编写的框架,它将defroute重命名为defpage并将其称为一天.显然是一种不公平的简化,但Noir到底带来了什么呢?为什么我会使用Noir而不是简单的组合+打嗝?

编辑/更新:Noir已被弃用,有趣的是在这里写:http://blog.raynes.me/blog/2012/12/13/moving-away-from-noir/.

clojure compojure noir

18
推荐指数
3
解决办法
5476
查看次数

IntelliJ + Maven + Tomcat中的Clojure Webapp

我正在使用Maven作为我的依赖管理器在IntelliJ中使用基于Compojure的Clojure Web应用程序.它基于我在示例引用的git存储库中找到的应用程序.当我尝试使用IntelliJ的Tomcat6配置运行应用程序时,每次引用Servlet异常时都会失败:

javax.servlet.ServletException: Wrapper cannot find servlet class tracker.core or a class it depends on
Run Code Online (Sandbox Code Playgroud)

另外,查看web.xml,IntelliJ无法识别servlet类(tracker.core突出显示).

一点背景:

这个应用程序最初是作为客户的概念证明而构建的,由我最近离开公司的同事编写.在过去的两天里,除了在这个项目上工作之外,我个人对clojure没有任何经验.使用Leiningen环服务器,我可以成功地让应用程序在jetty中运行.使用leiningen ring uberwar,由此产生的战争成功地部署并运行在tomcat中.

原始文件结构如下所示:

/tracker-webapp  
    /classes
    /lib
    /resources
    /src
        /tracker
            /core.clj (and other *.clj files)
    /test
    project.clj
Run Code Online (Sandbox Code Playgroud)

新的mavenized文件结构现在反映了前面提到的git repo中的示例:

/tracker-webapp
    /src
        /main
            /clojure
                /tracker
                    /core.clj (and other *.clj files)
            /webapp
                /WEB-INF
                    /web.xml
    /pom.xml
Run Code Online (Sandbox Code Playgroud)

我的web.xml:

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app
     PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
    "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>

  <display-name>Simple Clojure WebApp</display-name>
  <servlet>
    <servlet-name>myservlet</servlet-name>
    <servlet-class>tracker.core</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>myservlet</servlet-name>
    <url-pattern>/*</url-pattern> …
Run Code Online (Sandbox Code Playgroud)

tomcat clojure intellij-idea compojure maven

17
推荐指数
1
解决办法
935
查看次数