I've been experimenting with writing webapps in Clojure, and it's been pretty easy until now. I followed Chas Emerick's excellent screencast starting clojure and got an url shortener up and running pretty quickly. Next I wanted to be able to deploy it, and that's when the trouble started.
When I run it in development or deploy it to Jetty as the root webapp, everything is fine, but when I deploy it with a context path, it doesn't. Or, rather, it almost works. All my Compojure routes still work, but FORM
action links in HTML files are broken and give me 404's.
This is the Compojure route setup:
(defroutes app*
(rt/resources "/")
(GET "/" request (homepage request))
(POST "/shorten" request
(let [id (shorten (-> request :params :url))]
(response/redirect "/")))
(GET "/:id" [id] (redirect id)))
(def app (compojure.handler/site app*))
And here is the HTML for the homepage template:
<!DOCTYPE html>
<html>
<head>
<title>Insert title here</title>
<link type="text/css" rel="stylesheet" href="site.css" />
</head>
<body>
<form method="POST" action="shorten">
<input type="text" name="url" />
<input type="submit" value="Shorten!" />
</form>
</body>
</html>
The problem is the action="shorten"
URL. When deployed to Jetty with a context path of /example
everything work fine, until I trigger the form submit. Then Jetty complains that it can't find localhost:8080/shorten
which means (I think) that it's not being treated as a relative path, but an absolute one.
So, my question is: how to fix this? I guess I could just specify the full path in the action link, but that would be inflexible and make it harder to run the servlet in development. Is there a way to configure my way out of this? Or some magic URL prefix (like ~/
in Razor) that will just do the right thing?