smallseo.info

compojure

A concise routing library for Ring/Clojure

Compojure routes with different middleware

I'm currently writing an API in Clojure using Compojure (and Ring and associated middleware).

I'm trying to apply different authentication code depending on the route. Consider the following code:

(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?)))))

This doesn't work as expected because wrap-basic-authentication indeed wraps routes so it gets tried regardless of the wrapped routes. Specifically, if the requests needs to be routed to admin-routes, user-auth? will still be tried (and fail).

I resorted to use context to root some routes under a common base path but it's quite a constraint (the code below may not work it's simply to illustrate the idea):

(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
      public-routes
      (context "/user" []
        (-> user-routes
            (wrap-basic-authentication user-auth?)))
      (context "/admin" []
        (-> admin-routes
            (wrap-basic-authentication admin-auth?))))))

I'm wondering if I'm missing something or if there's any way at all to achieve what I want without constraint on my defroutes and without using a common base path (as ideally, there would be none).


Source: (StackOverflow)

How To Integrate Clojure Web Applications in Apache

Note

Given this OP was written about two years ago, rather than ask the same question again, I am wondering if step-by-step instructions exist, so that I can integrate a Noir or other Clojure web application into Apache, whether it's Jetty, Tomcat, or something else. Similar instructions exist for Django, and I think I understand that Python is being run in Django's case as an engine rather than a ring framework, so things are more complicated with Clojure web applications.

End Note

I'm deeply in love with Clojure, and Compojure seems like a neat web framework.

But it all fell apart when I wanted to deploy my application on a regular application server like Tomcat as a WAR. I actually had to write custom Ring handlers for static files and resources that would work on both local Jetty and Tomcat because the stock handlers didn't, and I had to prepend the context root everywhere manually.

I am negatively amazed that I had to write all this code to create the simplest web application conceivable that would run on both Jetty and Tomcat. I have only three possible explanations for this:

  1. Nobody uses Clojure/Compojure for anything other than local development with Jetty, i.e. in production
  2. Everybody deploys Clojure/Compojure apps on a dedicated Jetty without context root (LIke people do it with Node.js apps)
  3. There is a really simple way to circumvent the problems I ran into I wasn't aware of

Which of these is in your opinion the case? Or is it something else?

Edit:

Please note that creating a war file is a no-brainer with Maven/Leiningen and not what I mean. I'm wondering that I have to write so much code to make Compojure work with Tomcat, basic stuff like static file serving and context root awareness that should work out of the box.


Source: (StackOverflow)

Compojure: how to map query parameters

I'm trying to make any of the following mappings work to map http://mysite.org/add?http://sitetoadd.com or http://mysite.org/add?u=http://sitetoadd.com

  (GET "/add?:url" [url] url)
  (GET "/add?u=:url" [url] url)
  (GET "/add" {params :params} (params :u))
  (GET "/add" {params :params} (params "u"))
  (GET "/add" [u] u)

But it just fails and I don't know why. On the other hand, this works:

  (GET "/add/:url" [url] url)

but I can't use it because I have to pass a url and http://mysite.org/add/http://sitetoadd.com is invalid while http://mysite.org/add?http://sitetoadd.com is ok.

EDIT: dumping request i've seen that params is empty. I thought that it would contain POST and GET parameters, but the only place where I can find the params I pass is in :query-string ("u=asd"). It seems that a middleware is needed to parse query strings. My question stands still, by the way.


Source: (StackOverflow)

Missing form parameters in Compojure POST request

I'm having problems getting the form parameters in the following Compojure example:

(ns hello-world
  (:use compojure.core, ring.adapter.jetty)
  (:require [compojure.route :as route]))

(defn view-form []
(str "<html><head></head><body>"
   "<form method=\"post\">"
   "Title <input type=\"text\" name=\"title\"/>"
   "<input type=\"submit\"/>"
   "</form></body></html>"))

(defroutes main-routes
  (GET "/" [] "Hello World")
  (GET "/new" [] (view-form))
  (POST "/new" {params :params} (prn "params:" params))
  (route/not-found "Not Found"))

(run-jetty main-routes {:port 8088})

When submitting the form the output is always

params: {}

and I can't figure out why the title parameter is not in the params map.

I'm using Compojure 0.6.2.


Source: (StackOverflow)

How to run an arbitrary startup function in a ring project?

I've got a compojure/ring application I currently run with lein ring server that I'd like to compile to a .war so I can deploy it. I've got a definition, however, just like

 (def foo (start-scheduler))

That blocks the compilation and the generation of the .war. To circumvent this, I thought about moving the call to a startup function, but how would I call it when the server launches?

If I put the call inside the handler, I'd end up with the same problem as before.

Thanks!


Source: (StackOverflow)

All-in-one solution for using OAuth2 with Compojure

I am trying to integrate a compojure application with those OAuth2 providers: LinkedIn, Facebook, Google, and Twitter, using an all in one solution. I am aware of some existing java libraries such as scribe-java or spring-social that can help. But they suck when used from clojure. Is there a more clojure friendly solution to my goal? Or can anyone point me to a working sample / tutorial on how to reach my goal?


Source: (StackOverflow)

Clojure Webapp in Intellij + Maven + Tomcat

I am working with a Compojure based Clojure web application in IntelliJ using Maven as my dependency manager. It is based on an application I found at this git repository referenced by this example. When I try to run the application using IntelliJ's Tomcat6 configuration, it fails each time citing a Servlet Exception:

javax.servlet.ServletException: Wrapper cannot find servlet class tracker.core or a class it depends on

Additionally looking at the web.xml, IntelliJ does not recognize the servlet class (tracker.core is highlighted).

A little background:

This application was originally was built as a proof of concept for a client and written by my coworker who recently left the company. I personally have no experience with clojure beyond working on this project over the last two days. Using Leiningen ring server, I can successfully get the application to run in jetty. Using leiningen ring uberwar, the resulting war successfully deploys and runs in tomcat.

The original file structure looks like so:

/tracker-webapp  
    /classes
    /lib
    /resources
    /src
        /tracker
            /core.clj (and other *.clj files)
    /test
    project.clj

The new mavenized file structure now mirrors the example in the previously mentioned git repo:

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

My 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>
  </servlet-mapping>

</web-app>

Other Resources

Okay so I was going to post the other resources that I've looked at in this section but since I'm a Stack Overflow Newb I only get two links :/

P.S. This is my first question on Stack Overflow so if I missed something or you have any suggestions of anything I left out or do differently let me know. Thanks!


Source: (StackOverflow)

How do you use sessions with Compojure/Ring?

I'm developing a web application using Compojure and I would hugely appreciate a small and complete example of storing and retrieving session data.

Many thanks in advance, James.


Source: (StackOverflow)

Compojure or Noir for a UI-less webservice?

If one is planning to create a UI-less web service (receives JSON and/or XML, returns JSON and/or XML), does Noir provide anything useful over and above Compojure?


Source: (StackOverflow)

Escape/sanitize user input in Clojure/Compojure

I am using Clojure/Ring/Compojure-0.4/Enlive stack to build a web application.

Are there functions in this stack that would either strip HTML or HTML-encode (i.e. <a> to &lt;a&gt;) user-supplied strings in order to prevent XSS attacks?


Source: (StackOverflow)

Using Clojure with Vaadin

Has anyone tried implementing a web application with Clojure ( using Compojure ) and Vaadin ? I had seen an article on using Clojure with JWT for creating web apps. Vaadin is based on GWT so you get a lot of the advantages of GWT ( though Vaadin is completely Server-centric). And Clojure gives the advantage that you can use any Java Based Framework, so what thoughts on the Clojure + Vaadin based web application ?


Source: (StackOverflow)

how does one _model_ data from relational databases in clojure?

I have asked this question on twitter as well the #clojure IRC channel, yet got no responses.

There have been several articles about Clojure-for-Ruby-programmers, Clojure-for-lisp-programmers.. but what is the missing part is Clojure for ActiveRecord programmers .

There have been articles about interacting with MongoDB, Redis, etc. - but these are key value stores at the end of the day. However, coming from a Rails background, we are used to thinking about databases in terms of inheritance - has_many, polymorphic, belongs_to, etc.

The few articles about Clojure/Compojure + MySQL (ffclassic) - delve right into sql. Of course, it might be that an ORM induces impedence mismatch, but the fact remains that after thinking like ActiveRecord, it is very difficult to think any other way.

I believe that relational DBs, lend themselves very well to the object-oriented paradigm because of them being , essentially, Sets. Stuff like activerecord is very well suited for modelling this data. For e.g. a blog - simply put

class Post < ActiveRecord::Base
  has_many :comments
 end


 class Comment < ActiveRecord::Base
   belongs_to :post
 end

How does one model this in Clojure - which is so strictly anti-OO ? Perhaps the question would have been better if it referred to all functional programming languages, but I am more interested from a Clojure standpoint (and Clojure examples)


Source: (StackOverflow)

What's the "big idea" behind compojure routes?

I'm new to Clojure and have been using Compojure to write a basic web application. I'm hitting a wall with Compojure's defroutes syntax, though, and I think I need to understand both the "how" and the "why" behind it all.

It seems like a Ring-style application begins with an HTTP request map, then just passes the request through a series of middleware functions until it gets transformed into a response map, which gets sent back to the browser. This style seems too "low level" for developers, thus the need for a tool like Compojure. I can see this need for more abstractions in other software ecosystems as well, most notably with Python's WSGI.

The problem is that I don't understand Compojure's approach. Let's take the following defroutes S-expression:

(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>"))

I know that the key to understanding all of this lies within some macro voodoo, but I don't totally understand macros (yet). I've stared at the defroutes source for a long time, but just don't get it! What's going on here? Understanding the "big idea" will probably help me answer these specific questions:

  1. How do I access the Ring environment from within a routed function (e.g. the workbench function)? For example, say I wanted to access the HTTP_ACCEPT headers or some other part of the request/middleware?
  2. What's the deal with the destructuring ({form-params :form-params})? What keywords are available for me when destructuring?

I really like Clojure but I am so stumped!


Source: (StackOverflow)

noir vs compojure?

I'm having trouble understanding the point of clojure's Noir library. It seems to be a framework written on top of compojure that renames defroute to defpage and calls it a day. Obviously an unfair simplification, but what exactly does Noir bring to the table? Why would I use Noir instead of plain compojure+hiccup?

EDIT/UPDATE: Noir is deprecated, interesting write up here: http://blog.raynes.me/blog/2012/12/13/moving-away-from-noir/.


Source: (StackOverflow)

How to write multilingual applications in Clojure?

I'm trying to figure out how to create a Compojure-based web-site with multilingual support. Is there any solutions like i18n or something like that?


Source: (StackOverflow)